Google Sheets - Query Pivot - show all results - google-sheets

In google sheets have a pivot table with columns with text day ranges 1-30, 31-60, 61-90, 90-120, >120 where some records fall under those day ranges.
This is sample data:
Unique
Account Doc
Amount
Day Range
1
123456
1000
1-30
2
561530
2000
>120
3
123456
1500
61-90
4
25106
3000
1-30
I can get this data to pivot using standard pivot tables but users needs it to be clean without the pivot table buttons and formatting. I am trying to convert to google query function but I am stumped. I'd could try the option of pivoting and then calling the pivot to a query to remove the formatting but that seems redundant and there is a lot of other things happening in my sheet so afraid of making updating slow.
End result would look like below where the day ranges are pivoted and amount is showing for each record.
All columns need to be preserved as if there are null values all results appear even null/zero values for Amount as with column 31-60 and 91-120 showing the columns with no results. I use a unique id to ensure that all records come back as some of the
I can get the query to pivot with:
=query(rawdata,"Select Z,B,E,D,F,H,J, Sum(N) where B="&$C$31&" Group by Z,B,E,D,F,H,J pivot AA order by F",1)
However if the filter on B only has some day ranges and not others it will only show those columns with data.
Link to google sheet with sample data:
https://docs.google.com/spreadsheets/d/1seX4T3M8Mo9eVZYteyAbUG2zmWM9VCZ2-6oDd76QMA8/edit?usp=sharing
Result Query:
Unique
Account Doc
1-30
31-60
61-90
91-120
>120
1
123456
1000
2
561530
2000
3
123456
1500
4
25106
3000

try:
=ARRAYFORMULA(QUERY(QUERY({'Copy of raw data'!A:AA; IFERROR(VLOOKUP(
SEQUENCE(COUNTA(UNIQUE('Copy of raw data'!B2:B)&TRANSPOSE(UNIQUE('Copy of raw data'!AA2:AA)))), {
SEQUENCE(COUNTA(UNIQUE('Copy of raw data'!B2:B)&TRANSPOSE(UNIQUE('Copy of raw data'!AA2:AA)))),
SPLIT(FLATTEN(UNIQUE('Copy of raw data'!B2:B)&"×"&TRANSPOSE(UNIQUE('Copy of raw data'!AA2:AA))), "×"),
TO_TEXT(SPLIT(FLATTEN(UNIQUE('Copy of raw data'!B2:B)&"×"&TRANSPOSE(UNIQUE('Copy of raw data'!AA2:AA))), "×"))},
{0, 2, SEQUENCE(1, 24, 0, 0), 5}, 0))},
"select Col26,Col2,Col5,Col4,Col6,Col8,Col10,sum(Col14)
where 1=1 "&IF(B1="",, " and Col2="&B1)&"
group by Col26,Col2,Col5,Col4,Col6,Col8,Col10
pivot Col27
order by Col6", 1), "where Col1 is not null", 1))

Related

ImportRange Function to Ignore Empty Gaps between Sheet A and Sheet B

How can I combine 2 spreadsheets into one without any gaps? When I import range 2 sheets, there is a gap of ~1000 rows. To make sure there are no gaps between the 2 sheets, I usually create a query "Where Col1 is not null " but I am missing some info. :(
My spreadsheet: https://docs.google.com/spreadsheets/d/1aSnbySwNPEvkkXqw6ItuBpZ_6-o58HPlVicIHWD0Y4I/edit#gid=381064131
Thanks in advance.
You can use just being three columns:
=query({
importrange("https://docs.google.com/spreadsheets/d/1aSnbySwNPEvkkXqw6ItuBpZ_6-o58HPlVicIHWD0Y4I/edit#gid=0", "Sheet1!A2:C");
IMPORTRANGE("https://docs.google.com/spreadsheets/d/1aSnbySwNPEvkkXqw6ItuBpZ_6-o58HPlVicIHWD0Y4I/edit#gid=0", "Sheet2!A2:C")}, "Select * WHERE Col1 IS NOT NULL OR Col2 is not null OR Col3 is not null")
A second possible scenario for avoiding empty rows, no matter how many columns you have is wrapping your range or query in LAMBDA, and use FILTER associated with BYROW and COUNTA. If there are no elements in any row, then the count will be 0 and it will be filtered out:
=LAMBDA(quer,FILTER(quer, BYROW (quer, LAMBDA (each,COUNTA(each)))))({
importrange("https://docs.google.com/spreadsheets/d/1aSnbySwNPEvkkXqw6ItuBpZ_6-o58HPlVicIHWD0Y4I/edit#gid=0", "Sheet1!A2:C");
IMPORTRANGE("https://docs.google.com/spreadsheets/d/1aSnbySwNPEvkkXqw6ItuBpZ_6-o58HPlVicIHWD0Y4I/edit#gid=0", "Sheet2!A2:C")})
Both solutions return:

How can I sum across multiple sheets using a named range with multiple conditions?

I believe what I am trying to do should be simple in Google Sheets formulae, but any solution based on an Excel formula should be easily transferable.
Because additional characters will be added periodically, I have a named range: "Heroes".
Heroes
Bilbo
Gandalf
Saruman
Wormtongue
Tom Bombadil
For each hero, I have a worksheet in one overall workbook. On these worksheets, there are columns for Date, Time, Quest, and Count. Several times per day, a hero will venture out on a quest of a certain type, returning with a certain count as a prize. Each venture has its own row distinguishable by date and time. Eg-:
Date
Time
Quest
Count
12/4
3:00P
Ring
9
12/5
8:00A
Mordor
6
12/5
4:15P
Sting
3
Meanwhile, I have a summary worksheet, on which I am manually entering (for now... bonus points to help create an =arrayformula() or equivalent to grab all unique date/time combinations from each character's worksheet) the date and time at which one or a batch of heroes are sent to quest. I am trying to figure out the formula template that will sum the counts for each quest type for each hero at the specific date and time signified by its corresponding row (starting at 12/4, 3:00P, Ring, the count should be 9, for example, which is Bilbo's prize for questing at that time; of course, other heroes are also sent out at 3:00P, resulting in prizes for the other quests, and multiple heroes may venture on the same type of quest at any given time):
Date
Time
Ring
Sting
Mordor
Moria
12/4
3:00P
9
3
4
1
12/4
9:30P
1
0
8
0
12/5
8:00A
5
3
6
9
12/5
12:10A
3
1
3
8
12/5
4:15P
4
5
2
5
Since not every date and time in the summary sheet will exist on each hero's worksheet, I seem unable to use "SUMIFS", which functions in such a way that each sum_range and criteria_range are added on only across the same row when conditions are met. I think there is a SUMPRODUCT(), or INDEX(MATCH()) way to do this, but when including the named range to read across multiple worksheets, only the first hero's numbers were added in my tinkering with this.
I'm dancing around the solution here. Anyone care to tango ? Many thanks !
Sample Workbook for support: https://docs.google.com/spreadsheets/d/142IE9r2ip6YHsGdMr-zt_IHd6W7glqUId_UiGQnCUZs/edit?usp=sharing
it would be done like this:
=QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1)
if you want a specific order of places you can do:
=TRANSPOSE(SORT(TRANSPOSE(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)),
MATCH(FLATTEN(QUERY(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1), "limit 0", 1)),
{"Date"; "Time"; "Ring"; "Sting"; "Mordor"; "Moria"}, ), 1))
or manually like this:
=QUERY(QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1),
"select Col1,Col2,Col5,Col6,Col3,Col4")
if you thinking to outsmart it with the list of Heroes... don't. referring a range from other sheets requires the usage of INDIRECT. and surprise surprise, INDIRECT is not supported under ARRAYFORMULA so you cant build an array. at this point, you either re-think your life choices or you use a script where there is support for such indirected arrays. the best you can do without script is to hardcode it like:
=QUERY({
INDIRECT(Main!A2&"!A:D");
INDIRECT(Main!A3&"!A:D");
INDIRECT(Main!A4&"!A:D");
INDIRECT(Main!A5&"!A:D");
INDIRECT(Main!A7&"!A:D")},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
and ofc this will only work if sheet exists on the list and list does not contain empty cells otherwise you will get ARRAY error like this because Main!A6 sheet does not exist:
so to counter it we can do some slide of hand tricks with IFERROR which will allow us to not get the error and still use non-existent sheets and even empty cells so we can pre-program it for future additions like this:
=QUERY({
IFERROR(INDIRECT(IF(Main!A2="", 0, Main!A2)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A3="", 0, Main!A3)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A4="", 0, Main!A4)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A5="", 0, Main!A5)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A6="", 0, Main!A6)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A7="", 0, Main!A7)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A8="", 0, Main!A8)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A9="", 0, Main!A9)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A10="", 0, Main!A10)&"!A:D"),{"","","",""});
IFERROR(INDIRECT(IF(Main!A11="", 0, Main!A11)&"!A:D"),{"","","",""})},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
note: 4 columns in range A:D = 4 empty cells {"","","",""}

Google sheets Query function with Arrayformula

For each of the email id, I want to get latest 10 records by timestamp. How do I get the results with arrayformula? Query function is not important as long as I can still achieve this with arrayformula. Here is the sample data:
https://docs.google.com/spreadsheets/d/1YAHA02VM-5MXzVKhkxu_eODPKObpoz441mGX8lOFu5M/edit?usp=sharing
Try this on another sheet, row 1:
=arrayformula(query({query({Sheet1!$A:$C},"order by Col1 desc,Col2",1),{"Dupe position";countifs(query({Sheet1!$A2:$C},"select Col2 order by Col1 desc,Col2",0),query({Sheet1!$A2:$C},"select Col2 order by Col1 desc,Col2",0),row(Sheet1!$A2:$C),"<="&row(Sheet1!$A2:$C))}},"select Col1,Col2,Col3 where Col1 is not null and Col4 <= 10 order by Col1",1))
You can adjust the number of records found by adjusting Col4 <= 10, and also the final sort by altering order by Col1 at the end of the formula.
Explanation
This gets the data from Sheet1, sorts it by date desc then email asc:
query({Sheet1!$A:$C},"order by Col1 desc,Col2",1)
Then to the side of this data, a COUNTIFS() is used to get the number each time an email appears in the list above (since it's sorted desc, 1 represents the most recent instance).
countifs(<EmailColumnData>,<EmailColumnData>,row(<EmailColumn>),"<="&row(<EmailColumn>))
In place of <EmailColumnData> in the COUNTIF() is:
query({Sheet1!$A2:$C},"select Col2 order by Col1 desc,Col2",0)
In place of <EmailColumn> above, we only want the row number so we don't need the actual data. We can use:
Sheet1!$A2:$C
Various {} work as arrays to bring the data together.
Eg., {a,b,c;d,e,f} would result in three columns, with a, b, c in row 1 and d, e, f in row 2. , is a new column, ; is a return for a new row.
A final query around everything gets the 3 columns we need, where the count number in col 4 is <=10, then sorts the output by Col1 (date asc).
On second thoughts, maybe this is bit cheeky, but this might do it ( taken from conditional rank idea )
=ArrayFormula(filter(A2:C,countifs(A2:A,">="&A2:A,B2:B,B2:B)<=10,A2:A<>""))
EDIT
The above assumes (because the data is time-stamped) dups shouldn't occur. If they do and the data is pre-sorted, you can use row number as a proxy for time stamp as suggested by #Aresvik.
Alternatively, you could count separately
(a) only rows with a later timestamp
plus
(b) rows with the same time stamp but with earlier (or identical) row number
=ArrayFormula(filter(A2:C,countifs(A2:A,">"&A2:A,B2:B,B2:B)+countifs(A2:A,"="&A2:A,B2:B,B2:B,row(A2:A),"<="&row(A2:A))<=10,A2:A<>""))
I have added a new sheet ("Erik Help") with the following formula in A1:
=ArrayFormula({"Submitted Time","Email","Score";SORT(SPLIT(FLATTEN(QUERY(SORT(TRANSPOSE(SPLIT(TRANSPOSE(QUERY(IF(Sheet1!B2:B=TRANSPOSE(UNIQUE(FILTER(Sheet1!B2:B,Sheet1!B2:B<>""))),Sheet1!A2:A&"|"&Sheet1!B2:B&"|"&Sheet1!C2:C,),,COUNTA(Sheet1!A2:A)))," ",0,1)),SEQUENCE(MAX(COUNTIF(Sheet1!B2:B,Sheet1!B2:B))),0),"LIMIT 10")),"|",1,0),1,0)})
The number of records is set after LIMIT.
The order is set by the final two numbers: 1,0 (meaning "sort by column 1 in reverse order," which, as currently set, is sorting in reverse order by date/time).

Sum based on multiple row + header criteria

I have a problem with summing up my values from a data set, that's structured like this:
The goal is to sum the revenues separated by company and split by month, so the result is output in this way
I have tried it with some =sumifs + index/match and =sumproduct solutions, but can't seem to make it work.
Here's the sample file:
https://docs.google.com/spreadsheets/d/16xOoPCHDtcSRRojCkwcBorUc5dstgkXFPR6M_d5uY2U/edit#gid=0
On the "revenues" tab, in cell B4, try using the formula:
=SUMIFS(indirect(address(1,match(A4,Overview!$3:$3,0)-1,,,"Overview")&":"&address(1000,match(A4,Overview!$3:$3,0)-1)),Overview!A1:A1000,">="&B$2,Overview!A1:A1000,"<="&B$3)
To break it down, this bit helps figure out which revenue column to use by matching the name of the company and then taking the column before that:
match(A4,Overview!$3:$3,0)-1
This bit creates an address "Overview!$G$1":
address(1,match(A4,Overview!$3:$3,0)-1,,,"Overview")
This bit creates the 2nd part of the address i.e.":$G$1000":
"&":"&address(1000,match(A4,Overview!$3:$3,0)-1)
And the rest is a SUMIFS where it sums the revenue column for dates after the 1st of the month and before the last date of the month.
Be careful: your data is for 2020 and your summary table is using dates in 2021.
Reference:
SUMIFS
ADDRESS
MATCH
INDIRECT
use in A4:
=ARRAYFORMULA(QUERY(QUERY({SPLIT(FLATTEN(IF(
FILTER(Overview!G7:1000, MOD(COLUMN(Overview!G7:1000)+2, 3)=0)="",,
TEXT(Overview!A7:A25, "m")&"×"&
FILTER(Overview!G7:1000, MOD(COLUMN(Overview!G7:1000)+2, 3)=0)&"×"&
FILTER(Overview!G3:3, MOD(COLUMN(Overview!G3:3)+1, 3)=0))), "×");
SEQUENCE(12), SEQUENCE(12, 2,,)},
"select Col3,sum(Col2)
where Col1 is not null
group by Col3
pivot Col1", 0),
"offset 2", 0))

use Google Sheets QUERY to sum column where = x on a different sheet

I have a spreadsheet with 2 sheets in it,
I want to summarize the daily results by date.
I'm trying to use the query sum function to summarize everything since I wasn't able to do it with arrayformula.
but I'm not able to do it with a query as well.
I don't want to just copy-paste the sum function from each row to the next I want to just type the date I need in column A and get all the results in the different columns.
https://docs.google.com/spreadsheets/d/1ZsKXw32ycO_5KGD2I-Ug_GmqSIB_Z-D3Z1jlGd6fpTE/edit?usp=sharing
link to sheets.
getting the data from the database sheet.
I want to display the data-oriented by date and sumed.
for just 1 row you can simply do this and then drag down:
=ARRAYFORMULA(QUERY({TO_TEXT(DataBase!A:A), DataBase!B:E},
"select sum(Col5)
where Col1 = '"&TO_TEXT(A2)&"'
label sum(Col5)''", 0))
if array is needed then use:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A, QUERY(DataBase!A:E,
"select A,sum(E)
where A is not null
group by A
label sum(E)''", 0), 2, 0)))

Resources