Google sheets query multiple rows+cols to one cell with lookup table - google-sheets

Cannot figure out how to pull the results of a query with multiple rows and columns into single cells and find their details from my lookup table. Any help is greatly appreciated.
Trying this
=ArrayFormula(
QUERY({
QUERY({A4:A16,TEXTJOIN(",",TRUE,B4:C16)}, "SELECT Col1, Col2, Col3 WHERE Col1 MATCHES 'Core 1|Core 2|Core 3' LABEL Col1 'Core ID', Col2 'Full Result'")
}, "SELECT Col2 WHERE Col1 = Col1")
)
Sheet to help

It's always a headache trying to mix Query with ArrayFormula. They don't go well together.
I arrived at a nice formula, but the catch is that it relies on you sorting your data by Core Item first. You can easily achieve this with:
=SORT(A4:C16)
For this example, I placed this formula is cell N4. Then your resultant formula is:
=ArrayFormula(
{
"Core ID", "Full Result";
UNIQUE(FILTER(N4:N,N4:N<>"")),
SUBSTITUTE(
TRANSPOSE(
SPLIT(
REGEXREPLACE(
TEXTJOIN(
",",
,
UNIQUE(
TRANSPOSE(
IF(
TRANSPOSE(FILTER(N4:N,N4:N<>""))=FILTER(N4:N,N4:N<>""),
FILTER(O4:O,O4:O<>"")&
" ("&
VLOOKUP(FILTER(O3:O,O3:O<>""),A23:B53,2,)&
") - "&
FILTER(P4:P,P4:P<>"")&
" ("&
VLOOKUP(FILTER(P4:P,P4:P<>""),A23:B53,2,)&
")",
";"
)
)
)
),
",(;,)+",
";"
),";"
)
),
",",
CHAR(10)
)
})
It uses the Group Concatenate method I've adopted for stuff like this with UNIQUE, TRANSPOSE, and IF. This can probably be solved without using the precalculated SORT by substituting all instances of the N4:N, but doing it this way saves on computation time. If you need it gone, you can also hide the column or stow it in another sheet.

If you are ok breaking apart your formula then this would be an acceptable approach.
Start by Building your query criteria.
=ArrayFormula(
QUERY({QUERY({A4:A16,ArrayFormula(B4:B16&" ("&VLOOKUP(B4:B16,A23:B53,2,false)&") -
("&VLOOKUP(C4:C16,A23:B53,2,false)&")")}, "SELECT Col1, Col2 WHERE
Col1 MATCHES 'Core 1|Core 2|Core 3' LABEL Col1 'Core ID', Col2 'ALL Result'")},
"SELECT Col1, Col2 WHERE Col1 = Col1"))
Then in another column get the unique values and lastly, join the filtered values.
=UNIQUE(E4:E17)
=Join(Char(10),FILTER(F4:F12,E4:E12 = H4))
The downside to this is you will need to have multiple columns to achieve your desired result but it is easy to follow. Good luck!

Related

Modifying equations that use INDIRECT() inside ARRAYFORMULA()

From what I have read, it appears that INDIRECT() does not function with ARRAYFORMULA(), however have seen some custom workaround solutions for specific situations. Could anyone assist me with modifying the following equations such that I can use ARRAYFORMULA() with them?
Equation 1:
=IF($I$11<>"", SUMIFS(INDIRECT("'Earnings Pivot Statement'!"&$M$5&"6:"&$M$5&""),'Earnings Pivot Statement'!$A$6:A,">="&DATE(A2,1,1),'Earnings Pivot Statement'!$A$6:A,"<="&DATE(A2,12,31)), SUMIFS(INDIRECT("'Earnings Pivot Statement'!"&$P$5&"6:"&$P$5&""),'Earnings Pivot Statement'!$A$6:A,">="&DATE(A2,1,1),'Earnings Pivot Statement'!$A$6:A,"<="&DATE(A2,12,31)))
Equation 2:
=IFERROR(IFNA(SUMIFS(INDIRECT("'Earnings Pivot Statement'!"&$M$5&"6:"&$M$5&""),'Earnings Pivot Statement'!$A$6:A,">="&DATE(A2,1,1),'Earnings Pivot Statement'!$A$6:A,"<="&DATE(A2,12,31))/O2,"-"),"-")
Equation 3:
=SUMIFS(INDIRECT("'Earnings Pivot Statement'!"&$P$5&"6:"&$P$5&""),'Earnings Pivot Statement'!$A$6:A,">="&DATE(A2,1,1),'Earnings Pivot Statement'!$A$6:A,"<="&DATE(A2,12,31))
Appreciate any help I can get with understanding how to modify these!
Edit: Taking Erik's suggestion of not requiring INDIRECT(), I have managed to reference the same set of data using OFFSET() with the following:
=ARRAYFORMULA(IF($I$11:I11<>"", SUMIFS(OFFSET('Earnings Pivot Statement'!$A$6, 0, $M$2-1, COUNTA('Earnings Pivot Statement'!$A$6:A)+COUNTBLANK('Earnings Pivot Statement'!$A$6:A),1),'Earnings Pivot Statement'!$A$6:A,">="&DATE(A2:A,1,1),'Earnings Pivot Statement'!$A$6:A,"<="&DATE(A2:A,12,31)), SUMIFS(OFFSET('Earnings Pivot Statement'!$A$6, 0, $P$2-1, COUNTA('Earnings Pivot Statement'!$A$6:A)+COUNTBLANK('Earnings Pivot Statement'!$A$6:A),1),'Earnings Pivot Statement'!$A$6:A,">="&DATE(A2:A,1,1),'Earnings Pivot Statement'!$A$6:A,"<="&DATE(A2:A,12,31))))
However, ARRAYFORMULA() is only populating 1 cell currently, not sure why
You are looking up data from a pivot table, which seems like an unnecessary step. Try something like this to get the total directly from 'Earnings Input':
=query(
'Earnings Input'!A1:G,
"select year(A), sum(G)
where B is not null
group by year(A)
label year(A) 'Year', sum(G) 'Total' ",
1
)
=arrayformula(
iferror(
vlookup(
G18:G,
query(
'Earnings Input'!A1:G,
"select year(A), sum(G)
where B " & if(len(I11), "= '" & I11 & "' ", "is not null") & "
group by year(A)",
1
),
2, false
)
)
)
These formulas do not require any helper columns. Cell I11 is a drop-down list that lets you select a name to filter by, or leave empty to show all.
Additional data points can be obtained like this:
=arrayformula( if( not(len(G5)) * len(F9:F), "-", iferror( F9:F / E9:E ) ) )
=arrayformula(
if(
not(len(G5)) * len(F9:F),
"-",
iferror( 100% - G9:G / isnumber(G9:G) )
)
)
=if(
len(G5),
G5 & " % (" & to_text(round(average(G9:G), 2)) & ")",
"No filter"
)
See the new Solution3 sheet.
The solution above is still a bit verbose, primarily because of the report format you have chosen. It is usually easier to display the data for all categories at once. To get an idea what that would look like, try this:
=query(
'Earnings Input'!A1:G,
"select year(A), sum(G)
where B is not null
group by year(A)
pivot B
label year(A) 'Year', sum(G) 'Total' ",
1
)
=arrayformula(
if(
isnumber(B3:J15) * isnumber(B3:B15) * isnumber(B3:J3),
B3:J15 / B3:B15,
B3:J15
)
)
See the new Solution2 sheet.

Google Sheets complex array from multiple sheets

I am looking to build a formula that will check columns for a true value and if true return the first column name, in order...
Below is the formula I have been trying to build but it is not working as expected although I think I am close.
=ARRAYFORMULA(IF(HLOOKUP($A16,{Sheet1!$B$2:$E$5,Sheet2!$B$8:$E$11},{3,4,5},0)=TRUE,{Sheet2!$A$3:$A$5,Sheet1!$A$3:$A5,""))
Let me illustrate. Sheet 1 and Sheet 2 contain names with who has what (checkbox items). With a formula in cell B16 that will populate both to the right and down with all the names that contain a TRUE value in the looked up value (A:A).
Above image was manually typed in, the formula does not work at all.
Please help!
EDIT: Link to sheet
try:
=INDEX(IFERROR(VLOOKUP(A14:A, SUBSTITUTE(REGEXREPLACE(SPLIT(FLATTEN(
QUERY(SUBSTITUTE(QUERY(SPLIT(FLATTEN(
IF({B3:E5; B9:E11}=TRUE,
{B2:E2&"♦"&A3:A5&"♣"&ROW(A3:A5);
B8:E8&"♦"&A9:A11&"♣"&ROW(A9:A11)}, )), "♦"),
"select max(Col2) where Col2 is not null group by Col2 pivot Col1"),
" ", "♥"),,9^9)), " "), "(♣\d+)", ), "♥", " "),
SEQUENCE(1, COUNTUNIQUE(B2:E2, B8:E8))+1, 0)))
demo sheet
Here is another approach (similar to player0's, but different enough to warrant the separate answer:
=ArrayFormula(IFERROR(TRIM(SPLIT(VLOOKUP(FILTER(A3:A,A3:A<>""),REGEXREPLACE(SPLIT(FLATTEN(QUERY(QUERY(SPLIT(QUERY(FLATTEN({IF(Sheet1!B2:E<>TRUE,,Sheet1!B1:E1&"~|"&Sheet1!A2:A&",");IF(Sheet2!B2:E<>TRUE,,Sheet2!B1:E1&"~|"&Sheet2!A2:A&",")}),"Select * WHERE Col1 Is Not Null"),"|"), "Select MAX(Col2) where Col2 IS NOT NULL GROUP BY Col2 PIVOT Col1"),, 9^9)),"~"),"[,\s]+$",""),2,FALSE),","))))
I've added it into your spreadsheet in a new sheet ("Erik Help").
If you have more than two sheets' to include, just find this section of the formula and continue the pattern:
{ IF(Sheet1!B2:E<>TRUE,,Sheet1!B1:E1&"~|"&Sheet1!A2:A&","); IF(Sheet2!B2:E<>TRUE,,Sheet2!B1:E1&"~|"&Sheet2!A2:A&",") }

Finding the top 3 values and returning the column ID

Thank you beforehand for your kind response.
Problem: I am trying to do a sheet to sort out the 3 top categories of a given range as shown by the attached screen grab.
enter image description here
I only managed to get the results by using the "large" command. "=large(range,n)". Using this I got the value but what I need is the column index/id rather than the numeric values.
Any ideas on how I would go about achieving this?
Thanks for your reply.
Try the following maybe:
Formula in G2:
=TRANSPOSE(QUERY(TRANSPOSE({A$1:E$1;A2:E2}),"Select Col1 Order by Col2 desc limit 3"))
It's definitely possible in arrayformula.
Using vlookup, a sequence of numbers for the search key:
=arrayformula(sequence(max(if(A:E<>"",row(A:A),))-1,columns(A:E)))
...and a range of columns that are sorted by each row of numbers:
=arrayformula({
sequence((max(if(A:E<>"",row(A:A),))-1)*columns(A1:E1)),
sort({
array_constrain(int((row(A2:A)-2)/(columns(A:E)))+1,(max(if(A:E<>"",row(A:A),))-1)*columns(A1:E1),1),
array_constrain(iferror(split(flatten(if(A2:E<>"",A1:E1&char(9999),)&A2:E),char(9999)),),(max(if(A:E<>"",row(A:A),))-1)*columns(A1:E1),2)
},1,1,3,0)
})
The final formula for the solution, in cell G2:
=arrayformula(
array_constrain(
vlookup(
sequence(max(if(A:E<>"",row(A:A),))-1,columns(A:E)),
{sequence((max(if(A:E<>"",row(A:A),))-1)*columns(A1:E1)),sort({array_constrain(int((row(A2:A)-2)/(columns(A:E)))+1,(max(if(A:E<>"",row(A:A),))-1)*columns(A1:E1),1),array_constrain(iferror(split(flatten(if(A2:E<>"",A1:E1&char(9999),)&A2:E),char(9999)),),(max(if(A:E<>"",row(A:A),))-1)*columns(A1:E1),2)},1,1,3,0)}
,3,0),
max(if(A:E<>"",row(A:A),))-1,3)
)
It will work with blank cells in some of the rows.
The width of the source data is determined by:
=columns(A1:E1)
and the height of the source 'numbers' by:
=max(if(A:E<>"",row(A:A),))-1 (it needs to sit within an arrayformula).
you may use this superior formula:
=ARRAYFORMULA(ARRAY_CONSTRAIN(IFERROR(SPLIT(FLATTEN(SPLIT(QUERY(FILTER(
QUERY(SPLIT(FLATTEN(IF(A2:E="",,ROW(A2:A)&"×"&A2:E&"×"&A1:E1)), "×"),
"select Col3 where Col2 is not null order by Col1,Col2 desc"), COUNTIFS(
QUERY(SPLIT(FLATTEN(IF(A2:E="",,ROW(A2:A)&"×"&A2:E&"×"&A1:E1)), "×"),
"select Col1 where Col2 is not null order by Col1,Col2 desc"),
QUERY(SPLIT(FLATTEN(IF(A2:E="",,ROW(A2:A)&"×"&A2:E&"×"&A1:E1)), "×"),
"select Col1 where Col2 is not null order by Col1,Col2 desc"),
SEQUENCE(COUNTA(A2:E), 1, ROW(A2)), "<="&SEQUENCE(COUNTA(A2:E), 1, ROW(A2)))<4)&
FLATTEN(IFERROR(SEQUENCE(MAX((A2:E<>"")*ROW(A2:A)), 3)*
{"a", "a", 0})),,9^9), 0)), " ")), 9^9, 3))

Formula to fill a two dimensional grid with computed value from a table

Here is a problem to solve with a Google Sheets formula.
I have a big table (sheet “data” with headers on the first row) with those columns:
A, product reference
B: customer
C to F, KPI1 to KPI4
On another sheet, a grid of product references (A2:A) by customer (B1:1).
Now I need to fill each cell from the grid with the concatenation of KPIs (data!C24&"|"&data!D24&"|"&data!E24&"|"&data!F24)
Could you workout a single formula to fill all the cells?
Here is a sample spreadsheet with the data and grid sheet:
https://docs.google.com/spreadsheets/d/1iA_kw4kKw99Qk69X4tST9U-QN2SeG2EN3KEeyG6AtHs/edit?usp=sharing
I have worked out a formula which does the job, though with very poor performance on large dataset:
=ARRAYFORMULA(
IFNA(
VLOOKUP(
$B3:$B&"|"&C$2:$2,
ARRAYFORMULA(
{data!A2:A&"|"&data!B2:B,data!C2:C&"|"&data!D2:D&"|"&data!E2:E&"|"&data!F2:F}
),2,0
),""
)
)
Solution
Use an ArrayFormula on a Query with Pivot:
=ARRAYFORMULA(
QUERY(
{data!A2:A, data!B2:B, data!C2:C&"|"&data!D2:D&"|"&data!E2:E&"|"&data!F2:F},
"select Col1,max(Col3) where Col1 is not null group by Col1 pivot Col2",0
)
)
a shorter version of previous answer (no need for pre-sorting coz pivot will sort it on its own):
=ARRAYFORMULA(QUERY(
{data!A2:A, data!B2:B, data!C2:C&"|"&data!D2:D&"|"&data!E2:E&"|"&data!F2:F},
"select Col1,max(Col3) where Col1 is not null group by Col1 pivot Col2", 0))
Try this on the first cell of your grid:
=ArrayFormula(query(sort({data!A:A,data!B:B,transpose(substitute(query(transpose(data!C:F),,4)," ","|"))},1,true,2,true),"select Col1, max(Col3) where Col1 is not null group by Col1 pivot Col2",0))

Phrase Frequency formula for Google Sheets

I have a column of search terms and would like to find out all the two-word phrases in this column and the frequency of each of all them. Does anyone know of a formula in Google Sheets that can help me accomplish this?
=ARRAYFORMULA(IFERROR(QUERY(IF(SPLIT(A1:A, " ")>0, A1:A, ),
"select Col2,count(Col2)
where Col2 is not null
and Col3=''
group by Col2
label count(Col2)'frequency'"),
QUERY(IF(SPLIT(A1:A, " ")>0, A1:A, ),
"select Col2,count(Col2)
where Col2 is not null
group by Col2
label count(Col2)'frequency'")))
pste in C2 and drag down:
=COUNTA(FILTER(A:A, SEARCH("*"&B2&"*", A:A)))

Resources