Google Query - Show TOTAL Row as blank or 0% cells if Query table returns empty rows or #VALUE! error - stack
I am calculating a TOTAL's row for an FTR table that i want to stack below the FTR table like this:
=ArrayFormula(
{
FTR Table ;
TOTAL
}
The FTR Table is also calculated via Google Query. The table contains some cells having 0%. For a particular Year, say 2018 (Cell C1), the FTR Table may look like below:
+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+
| FTR % | 2018-Jan | 2018-Feb | 2018-Mar | 2018-Apr | 2018-May | 2018-Jun | 2018-Jul | 2018-Aug | 2018-Sep | 2018-Oct | 2018-Nov | 2018-Dec |
+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+
| Allana | | | | | | | | 0.00% | | 76.92% | 85.00% | 83.72% |
| Mark | | | | 0.00% | | | 0.00% | 75.00% | 86.21% | 76.32% | 90.16% | 91.43% |
| Jane | | 57.50% | 68.97% | 89.47% | 81.82% | 81.36% | 91.11% | 90.24% | 85.71% | 88.89% | 82.69% | 89.61% |
| Santorin | | | | 0.00% | | | | | | | | |
| Lamaiye | | | | | | | | | | | | 85.71% |
| Suez | 80.00% | | 86.67% | 75.00% | 81.08% | 87.27% | 91.80% | 79.69% | 81.43% | 81.40% | 71.70% | 76.00% |
+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+
and the TOTAL row may show as AVERAGE % of each Year-Month Column :
+-------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| TOTAL | 80.00% | 57.50% | 77.82% | 82.24% | 81.45% | 84.31% | 91.46% | 81.64% | 84.45% | 80.88% | 82.39% | 85.29% |
+-------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
Note: See 2018-July & 2018-Aug where there are 0%'s but the AVERAGE is calculated correctly.
2018-July = 91.46%
2018-Aug = 81.64%
But for a particular Year 2017, the table may just show 0% and blank Column Headers also, to maintain Column structure of the stacked tables (one above the other).
+-------+--+--+--+----------+----------+
| FTR % | | | | 2017-Aug | 2017-Dec |
+-------+--+--+--+----------+----------+
| Mark | | | | | 0.00% |
| Jane | | | | 0.00% | |
+-------+--+--+--+----------+----------+
However, the problem arises here for the TOTAL row as it results in
+---------+
| #VALUE! |
+---------+
with error description: Error:Unable to parse query string for Function QUERY parameter 2: AVG_SUM_ONLY_NUMERIC
This single cell value for the TOTAL row breaks the Tables Column structure and the above stacked Tables e.g. the FTR Table also does not show up. I need to have some way to show the TOTAL row Column cells as BLANKS or 0%'s (like as shown below) whenever there is such kind of error:
+-------+-------+-------+-------+-------+-------+
| TOTAL | 0.00% | 0.00% | 0.00% | 0.00% | 0.00% |
+-------+-------+-------+-------+-------+-------+
I cannot share any Spreadsheet due to legal restrictions on my laptop, so I am pasting the Google Query for the TOTAL's row only as it is similar to the FTR table, except for a few changes:
=ARRAYFORMULA(TRANSPOSE(QUERY(QUERY(QUERY({QUERY(
{TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")&
IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))},"select Col1,Col8,Col15,Col22,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' group by Col1,Col8,Col15,Col22 order by Col8"),
IFNA(VLOOKUP(QUERY({TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")&IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))},
"select Col1,Col8,Col15,Col22,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' group by Col1,Col8,Col15,Col22 order by Col8")
,QUERY({TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")&
IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))},
"select Col1,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' and Col16!= 'NO - all fine' AND Col16!='-' group by Col8,Col1")
,2,0))
}
,"SELECT Col1,Col2,Col3,Col4,(1-Col6/Col5 * 1) WHERE (1-Col6/Col5 * 1)>0 label Col1 'A', Col2 'B', Col3 'C', Col4 'D', (1-Col6/Col5 * 1) 'diff'"),
"SELECT Col4, AVG(Col5) GROUP BY Col4 LABEL AVG(Col5) 'TOTAL' FORMAT AVG(Col5) '0.00%'"),"SELECT Col2")))
Credits: Thanks to #player0 for showing me this method of Stacking Tables whilst maintaining the Column structure.
EDIT:
I tried the below solution with an IFERROR() function (also shown earlier by #Player0, which adds a blank row between two tables), for generating the TOTAL row if no data or on error:
=TRANSPOSE(
QUERY(
TRANSPOSE(
IFERROR(
ARRAYFORMULA(TRANSPOSE(QUERY(QUERY(QUERY({QUERY( {TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")& IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))},"select Col1,Col8,Col15,Col22,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' group by Col1,Col8,Col15,Col22 order by Col8"), IFNA(VLOOKUP(QUERY({TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")&IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))}, "select Col1,Col8,Col15,Col22,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' group by Col1,Col8,Col15,Col22 order by Col8") ,QUERY({TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")& IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))}, "select Col1,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' and Col16!= 'NO - all fine' AND Col16!='-' group by Col8,Col1") ,2,0)) } ,"SELECT Col1,Col2,Col3,Col4,(1-Col6/Col5 * 1) WHERE (1-Col6/Col5 * 1)>0 label Col1 'A', Col2 'B', Col3 'C', Col4 'D', (1-Col6/Col5 * 1) 'diff'"), "SELECT Col4, AVG(Col5) GROUP BY Col4 LABEL AVG(Col5) 'TOTAL' FORMAT AVG(Col5) '0.00%'"),"SELECT Col2 FORMAT Col2 '0.00%'"))),
ARRAYFORMULA(SPLIT(REPT("TOTAL ♠", COLUMNS(TRANSPOSE(QUERY({TEXT('Study Report'!G1:G,"yyyy-mmm;;")&"♦"&'Study Report'!N1:N, 'Study Report'!B1:F, TEXT('Study Report'!G1:G,"yyyy;;"), TEXT('Study Report'!G1:G,"yyyy-mm;;"), 'Study Report'!H1:T, TEXT('Study Report'!G1:G,"yyyy-mm;;")& IF('Study Report'!G1:G="",,"♥"&TEXT('Study Report'!G1:G, "yyyy-mmm;;"))},"select Col22,count(Col2) where Col8 is not null and Col7 = '"&C1&"' and Col13 != 'Cancelled' group by Col22")))), "♠") ))),"SELECT Col1 FORMAT Col1 '0.00%'"))
The Only issue is that all the Values will show the word TOTAL for all cells, instead of only 1st cell and rest cells as 0.00%:
+--------+--------+--------+--------+--------+--------+
| TOTAL | TOTAL | TOTAL | TOTAL | TOTAL | TOTAL |
+--------+--------+--------+--------+--------+--------+
Any better idea instead to show it like below:
+-------+-------+-------+-------+-------+-------+
| TOTAL | 0.00% | 0.00% | 0.00% | 0.00% | 0.00% |
+-------+-------+-------+-------+-------+-------+
Related
Count all element occurences in list in cell(by list I mean a string with seperators) in google docs
I have two tables Table 1: | list_of_ids | 1 | 1; 2 | 2 | 3 | 3 | 4; 5; 1 | Table 2: | id | count | 1 | 1 | 2 | 2 | 2 | 1 | 3 | 4 | 1 | 4 | 6 | 0 | how do I automatically fill in count? I currently have a very unsatisfying and hacky way of doing it like this: list_of_ids is formatted like ;id;id;id; instead of id; id; id count =COUNTIF(range, "*"&";"&id_cell&";"&"*") is there a way to do it more properly, so to not force users to write ids in such a way?
try: =INDEX(QUERY(FLATTEN(SPLIT(TEXTJOIN(";"; 1; A:A); ";")); "select Col1,count(Col1) where Col1 is not null group by Col1 label count(Col1)''")) or: =ARRAYFORMULA(IF(C2:C="";;IFNA(VLOOKUP(C2:C; QUERY(FLATTEN(SPLIT(TEXTJOIN(";"; 1; A:A); ";")); "select Col1,count(Col1) where Col1 is not null group by Col1 label count(Col1)''"); 2; 0); 0)))
Group table, count rows, pad columns with spaces, and concat everything into one big string in a Google Sheet
I have already come up with a working formula but I feel like it is horribly inefficient. I feel like there is probably a better way to do this. I have a table like so: | ID | Name | Status | |-------|--------|-----------| | ID001 | User 3 | closed | | ID002 | User 5 | cancelled | | ID003 | User 2 | closed | | ID004 | User 3 | pending | | ID005 | User 3 | closed | | ID006 | User 1 | closed | | ID007 | User 3 | hold | | ID008 | User 5 | hold | | ID009 | User 4 | closed | | ID010 | User 3 | closed | | ID011 | User 4 | pending | | ID012 | User 4 | pending | | ID013 | User 2 | hold | | ID014 | User 3 | closed | | ID015 | User 2 | pending | | ID016 | User 2 | closed | | ID017 | User 1 | pending | | ID018 | User 5 | pending | | ID019 | User 2 | open | | ID020 | User 4 | hold | | ID021 | User 2 | open | | ID022 | User 2 | pending | | ID023 | User 5 | closed | | ID024 | User 3 | closed | | ID025 | User 5 | open | | ID026 | User 5 | closed | | ID027 | User 4 | cancelled | | ID028 | User 1 | hold | | ID029 | User 4 | open | | ID030 | User 1 | pending | | ID031 | User 5 | pending | | ID032 | User 3 | cancelled | | ID033 | User 2 | closed | | ID034 | User 5 | open | | ID035 | User 2 | open | | ID036 | User 2 | pending | | ID037 | User 3 | hold | | ID038 | User 4 | open | | ID039 | User 5 | open | | ID040 | User 2 | pending | | ID041 | User 3 | pending | | ID042 | User 5 | cancelled | | ID043 | User 2 | pending | | ID044 | User 2 | cancelled | | ID045 | User 1 | open | | ID046 | User 2 | pending | | ID047 | User 1 | pending | | ID048 | User 2 | cancelled | | ID049 | User 2 | pending | I want to group by Name, count the number of rows where Status is not cancelled, closed, or hold. So, using a simple query I get this: =QUERY( A2:C, " SELECT B, COUNT(A) WHERE A IS NOT NULL AND C != 'hold' AND C != 'cancelled' AND C != 'closed' GROUP BY B LABEL COUNT(A) '' " ) Becomes: | User 1 | 4 | |--------|---:| | User 2 | 10 | | User 3 | 2 | | User 4 | 4 | | User 5 | 5 | Then I want to concatenate everything into one big string -- but the Name column should be padded with spaces on the right such that the numbers on the left line up (when using a monospace font), and then pad the total so it is right aligned (when using a monospace font). The idea is, the total/summary table should be in one call whose font will be set to monospace. I came up with the below formula that works (screenshots below). But I am wondering if there is a better, more efficient way to do this. =JOIN( CHAR(10) , QUERY( TRANSPOSE( SORT( { UNIQUE( FILTER( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) & REPT( " ", MAX( FILTER( LEN(Sheet1!B2:B) , Sheet1!A2:A <> "" , Sheet1!C2:C <> "closed" , Sheet1!C2:C <> "cancelled" , Sheet1!C2:C <> "hold" ) ) - LEN(IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B)) ) & " :" , Sheet1!A2:A <> "" , Sheet1!C2:C <> "closed" , Sheet1!C2:C <> "cancelled" , Sheet1!C2:C <> "hold" ) ) , ARRAYFORMULA( REPT( " ", MAX( LEN( COUNTIFS( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) , UNIQUE( FILTER( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) , Sheet1!A2:A <> "" , Sheet1!C2:C <> "closed" , Sheet1!C2:C <> "cancelled" , Sheet1!C2:C <> "hold" ) ) , Sheet1!A2:A , "<>" , Sheet1!C2:C , "<>closed" , Sheet1!C2:C , "<>cancelled" , Sheet1!C2:C , "<>hold" ) ) ) - LEN( COUNTIFS( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) , UNIQUE( FILTER( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) , Sheet1!A2:A <> "" , Sheet1!C2:C <> "closed" , Sheet1!C2:C <> "cancelled" , Sheet1!C2:C <> "hold" ) ) , Sheet1!A2:A , "<>" , Sheet1!C2:C , "<>closed" , Sheet1!C2:C , "<>cancelled" , Sheet1!C2:C , "<>hold" ) ) ) & COUNTIFS( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) , UNIQUE( FILTER( IF(Sheet1!B2:B = "", "!!! UNASSIGNED !!!", Sheet1!B2:B) , Sheet1!A2:A <> "" , Sheet1!C2:C <> "closed" , Sheet1!C2:C <> "cancelled" , Sheet1!C2:C <> "hold" ) ) , Sheet1!A2:A , "<>" , Sheet1!C2:C , "<>closed" , Sheet1!C2:C , "<>cancelled" , Sheet1!C2:C , "<>hold" ) ) } , 1 , TRUE ) ) , , 999^99 ) )
Given your answers to my questions in comments, this is what I came up with (without spending hours at least): =ArrayFormula(JOIN(CHAR(10),SORT(UNIQUE(FILTER(B2:B&REPT(" ",(MAX(LEN(B2:B)+1)-LEN(B2:B))),B2:B<>"")),1,1)&":"&(REPT(" ",(MAX(LEN(COUNTIF(FILTER(B2:B,NOT(ISNUMBER(SEARCH(C2:C,"cancelled/closed/hold")))),FILTER(B2:B,NOT(ISNUMBER(SEARCH(C2:C,"cancelled/closed/hold")))))))+1)-LEN(QUERY(FILTER({B2:B,C2:C},NOT(ISNUMBER(SEARCH(C2:C,"cancelled/closed/hold")))),"Select COUNT(Col2) GROUP BY Col1 LABEL COUNT(Col2) ''"))))&QUERY(FILTER({B2:B,C2:C},NOT(ISNUMBER(SEARCH(C2:C,"cancelled/closed/hold")))),"Select COUNT(Col2) GROUP BY Col1 LABEL COUNT(Col2) ''"))) It cuts your formula down by 433 non-space characters (i.e. by nearly half). Typically, I explain my formulas. But in this case, I trust you won't mind if I leave it to you to tear apart and study the formula. ** EDIT BY IMTheNachoMan ** Unminified formula: =ArrayFormula( JOIN( CHAR(10), SORT( UNIQUE( FILTER( B2:B & REPT( " ", ( MAX( LEN(B2:B) + 1 ) - LEN(B2:B) ) ), B2:B <> "" ) ), 1, 1 ) & ":" & ( REPT( " ", ( MAX( LEN( COUNTIF( FILTER( B2:B, NOT( ISNUMBER( SEARCH( C2:C, "cancelled/closed/hold" ) ) ) ), FILTER( B2:B, NOT( ISNUMBER( SEARCH( C2:C, "cancelled/closed/hold" ) ) ) ) ) ) ) + 1 ) - LEN( QUERY( FILTER( { B2:B, C2:C }, NOT( ISNUMBER( SEARCH( C2:C, "cancelled/closed/hold" ) ) ) ), "Select COUNT(Col2) GROUP BY Col1 LABEL COUNT(Col2) ''" ) ) ) ) & QUERY( FILTER( { B2:B, C2:C }, NOT( ISNUMBER( SEARCH( C2:C, "cancelled/closed/hold" ) ) ) ), "Select COUNT(Col2) GROUP BY Col1 LABEL COUNT(Col2) ''" ) ) )
Transferring rows from a table to join similar rows in the same table [duplicate]
I'm trying to merge rows with same IDs in Google Sheets From: ID | Category Augur | A1 Augur | A2 Augur | A3 Augur1 | A1 Augur1 | A2 Augur1 | A3 To: ID | Category Augur | A1; A2; A3 Augur1 | A1; A2; A3 Is there an automatic way to do it in Google Sheets itself, using its native functions?
=ARRAYFORMULA(QUERY({INDEX(QUERY(A1:B, "select A,count(A) where A is not null group by A pivot B", 0), , 1), REGEXREPLACE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(IF(ISNUMBER(QUERY(A1:B, "select count(A) where A is not null group by A pivot B", 0)), INDEX(QUERY({A1:A,B1:B&";"}, "select count(Col1) where Col1 is not null group by Col1 pivot Col2 offset 1", 0), 1,), )) , , 999^99))), ";$", )}, "offset 1", 0))
How to count a value from a cell which contains multiple values?
I have a table with cells which contain comma-separated multiple values as follows: +----------+ | Column A | |----------| | a, b | |----------| | a, b, d | |----------| | b, c | |----------| | c, d, e | +----------+ I would like to get a table which counts the number of a, b, ..., e as follows: +-----------------------+ | Column A | Column B | |-----------------------| | a | 2 | |-----------------------| | b | 3 | |-----------------------| | c | 2 | |-----------------------| | d | 2 | |-----------------------| | e | 1 | +-----------------------+ Is there any Google Sheets or LibreOffice Calc spreadsheet formula to do this?
C1: =UNIQUE(TRANSPOSE(SPLIT(TEXTJOIN(" ,",1,A:A)," ,"))) D1: =ARRAYFORMULA(IF(LEN(C:C),COUNTIF(A:A,"=*"&C:C&"*"),))
=QUERY(TRANSPOSE(SPLIT(TEXTJOIN(" ,",1,A:A)," ,")), "select Col1, count(Col1) where Col1 is not null group by Col1 label count(Col1) ''")
={UNIQUE(TRANSPOSE(SPLIT(TEXTJOIN(" ,",1,A:A)," ,"))), ARRAYFORMULA(IF(LEN(UNIQUE(TRANSPOSE(SPLIT(TEXTJOIN(" ,",1,A:A)," ,")))), COUNTIF(A:A,"=*"&UNIQUE(TRANSPOSE(SPLIT(TEXTJOIN(" ,",1,A:A)," ,")))&"*"),))}
Search Data for matching row/array
I want to search a set of data to see if it contains a matching set of values eg. +------+------+------+------+ | Col1 | Col2 | Col3 | Col4 | +------+------+------+------+ | A | B | C | D | +------+------+------+------+ would match the last row in +------+------+------+------+ | Col1 | Col2 | Col3 | Col4 | +------+------+------+------+ | B | C | D | A | | A | D | B | C | | A | B | B | D | | D | C | B | A | | A | B | C | D | +------+------+------+------+ A boolean return would be fine. Any pointers would be greatly appreciated. Cheers
Assumptions Columns to check: A:D Values to check are in F1:I1 Result in K1 - boolean Code =NOT(ISERROR( QUERY({ArrayFormula(A1:A&B1:B&C1:C&D1:D)}, "select * where Col1='"&JOIN("",F1:I1)&"'",0) ) ) Picture