Using Query to select column based on the headers - google-sheets

I have a dynamic table where columns are moved every now and then. Therefore, I would like to reference my column name in my query. Unfortunately I do not know so well and the internet raises more questions.
My formula looks like this:
`=query('X Source'!A:AP, "select D, E, AA, AM, X, A where "&if(month(now())=1,"(month(A)<11)","(month(A) <=month(now())-2)")&" and (V like 'C & G' or V like 'SAS' or V like 'SXS D' or V like 'DIR') Order By A desc")
D = Cinter
E = Cluster
AA = Creation Date
AM = Change Ow
X = Title
A = Date`
Do you have any idea ? I would like not to write a script.
I have already tried with the function filter to bypass but there I get no further because of the filtering after month.
`={FILTER('X Source'!AA:AA, 'X Source'!V:V="SAS",'X Source'!X:X<>"%BY SB%",'X Source'!X:X<>"%SB ONLY%", month('X Source'! AA:AA)=month(today())-1);FILTER('X Source'!AA:AA,'X Source'!V:V="SXS D",'X
Source'!X:X<>"%BY SB%",'X Source'!X:X<>"%SB ONLY%"`

You can define the following Named Function. (Data > Named functions > Add new function)
Name:
BETTERQUERY(range, better_query, headers)
Definition
=QUERY({range},IF(IFERROR(SPLIT(better_query,"`")=better_query,1),better_query,
REGEXREPLACE(REDUCE(better_query,REGEXEXTRACT(better_query,REGEXREPLACE(
REGEXREPLACE(better_query,"([()\[\]{}|\\^$.+*?])","\\$1"),"`(.*?)`","`($1)`")),
LAMBDA(acc,cur,SUBSTITUTE(acc,cur,IFNA("Col"&MATCH(cur,INDEX(range,1),0),cur)))),
"`(Col\d+)`","$1")),headers)
And then use it like this:
=BETTERQUERY('X Source'!A:AP',"select `Cinter`, `Cluster`, `Creation date` ...",1)
For more information on how this works see How to Use Column Names in QUERY

You could use MATCH to find the numbers of columns, and grab your range in curly brackes so you can refer them as Col1,Col2,Col3 instead of A,B,C
Just to make it more dinamic and you could change your range, I wrapped it in LAMBDA. With the headers I matched all your values and joined them with comma. 'date' only matched that colum. Column V I had my doubts about if it was a mistake when you said which columns was located at which headers. Please change "Title" in ""Col"&MATCH("Title",INDEX(range,1),0)" to the actual desired header title (that now is in V column) so it matches correctly:
=LAMBDA(range,
LAMBDA(headers,date,title,query({range}, "select "&headers&" where "&if(month(now())=1,"(month("&date&")<11)","(month("&date&") <=month(now())-2)")&" and ("&title&" like 'C & G' or "&title&" like 'SAS' or "&title&" like 'SXS D' or "&title&" like 'DIR') Order By "&date&" desc"))(
JOIN(",",INDEX("Col"&MATCH({"Cinter","Cluster","Creation Date","Change Ow","Title","Date"},INDEX(range,1),0))),
"Col"&MATCH("Date",INDEX(range,1),0),
"Col"&MATCH("Title",INDEX(range,1),0)
))
('X Source'!A:AP)
In my dummy example with random columns, the inside part of the query would look like this:
"select Col7,Col3,Col15,Col20,Col11,Col12 where (month(Col12)<11) and
(Col11 like 'C & G' or Col11 like 'SAS' or Col11 like 'SXS D' or Col11
like 'DIR') Order By Col12 desc"
UPDATE with other Locale
=LAMBDA(range; LAMBDA(headers;date;pl;query({range}; "select "&headers&" where "&if(month(now())=1;"(month("&date&")<11)";"(month("&date&") <=month(now())-2)")&" and ("&pl&" like 'C & G' or "&pl&" like 'SAS' or "&pl&" like 'SXS D' or "&pl&" like 'DIR') Order By "&date&" desc";1))( JOIN(",";INDEX("Col"&MATCH({"Cinter";"Cluster ";"Creation Date";"Change Owner";"Title";"Date"};INDEX(range;1);0))); "Col"&MATCH("Date";INDEX(range;1);0); "Col"&MATCH("PL";INDEX(range;1);0) )) ('X Source'!A1:AS)

Related

Passing QUERY() as a parameter to a Google Sheets LAMBDA function

Google Sheets offers passing in parameters to lambdas as such:
=LAMBDA(x, y, x + y)(100, 200)
I was thinking of taking 2 columns from another Sheet, filter it with QUERY and then pass those 2 columns into the LAMBDA. Basically the 2 columns were a key and a CSV text that I wanted to split in one go.
=lambda(a, b, split(b, ","))(query('Alias Key Raw'!A1:B, "select * where A starts with 'X'"))
This gives the following ERROR Wrong number of arguments to call following LAMBDA function. Expected 2 arguments, but got 1 arguments.. Given that QUERY provides 2 columns of actual values, I thought this would be possible.
=byrow(query('Alias Key Raw'!A1:B, "select * where A starts with 'X'"), lambda(row, split(row, ",")))
This gives me only column A. No error otherwise. All of column B is ignored it appears
I've tried using BYCOL, BYROW, etc, and a lot of errors are ERROR Wrong number of arguments to call following LAMBDA function. Expected 2 arguments, but got 1 arguments.
Data
Input into the lambda
Key
Lineages
CU
B.1.1.529.5.1.26
CV
B.1.1.529.2.75.3.1.1.3
XA
B.1.1.7,B.1.177
XB
B.1.634,B.1.631
XC
AY.29,B.1.1.7
XAZ
BA.2.5,BA.5,BA.2.5
XBC
BA.2*,B.1.617.2*,BA.2*,B.1.617.2*
Expected
Output from the lambda
Key
Lineages
XA
B.1.1.7
B.1.177
XB
B.1.634
B.1.631
XC
AY.29
B.1.1.7
XAZ
BA.2.5
BA.5
BA.2.5
XBC
BA.2*
B.1.617.2*
BA.2*
B.1.617.2*
Note: There can be any number of lineages in the CSV cell
Updated
=ArrayFormula(
LAMBDA(a, {QUERY({a},"Select Col1"),SPLIT(QUERY({a},"Select Col2"),",")})
(QUERY('Alias Key Raw'!A1:B, "select * where A starts with 'X'",1)))
Explanaition:
using an Array {} to return:
Col1: {QUERY({a},"Select Col1"),...}
Col2: {...,SPLIT(QUERY({a},"Select Col2"),",")}
Of the Query QUERY('Alias Key Raw'!A1:B, "select * where A starts with 'X'",1) found in the Lambda call named a
Used formulas help
ARRAYFORMULA - LAMBDA - QUERY - SPLIT
Perhaps worth pointing out that the expected data can be returned with a more compact formula that uses neither QUERY nor LAMBDA:
=filter({A1:A,split(B1:B,",")},regexmatch(A1:A,"^X"))

How can I repeat a query with multiple columns N times with a join who only take ONE column?

I am using this:
=IFERROR(QUERY(Opgivelser!A:E; "select D,A,B where E = TRUE");"Vælg fordybelsesområder")
for this:
And it works as intended but I also want to repeat it i.e twice or based on a cells value i.e D2.
I have tried to to use this:
=ArrayFormula(TRANSPOSE(SPLIT(JOIN(","; IFERROR(REPT(IFERROR(QUERY(Opgivelser!A:E; "select D,A,B where E = TRUE"); "Vælg fordybelsesområder") & ","; D2))); ",")))
But that one prompts an error about ONE row/column.
What will I have to change? Or is there an even more simple or logical syntax for this?
try:
=ARRAYFORMULA(SPLIT(TRANSPOSE(SPLIT(REPT(QUERY(TRANSPOSE("♠"&
QUERY(TRANSPOSE("♦"&IFERROR(QUERY(Opgivelser!A:E;
"select D,A,B where E = TRUE"); "Vælg fordybelsesområder"))
;;9^9));;9^9); F1); "♠")); "♦"))

IFS statement with multiple nested QUERY functions

With a fair amount of help from SO folks, I managed to put together about 15 QUERY tabs used to extract necessary data for reporting.
In order to make it tidy, I'd like to enclose all these queries in an IFS statement referring to a Data Validation cell and run the QUERY by simply changing the value from the validation cell.
I managed to get it running with no errors, however, I get a single cell output.
What I am using for this is:
=IFS('Validation'!$A$1 = "Giberish",
{QUERY('All'!$A$5:$AP,
"SELECT AJ, '" & IDBlah & "', 'Blah'
WHERE AJ IS NOT NULL
LABEL '" & IDBlah & "' 'ID',
'Blah' 'BlahBlahBlah'",1)},
'Validation'!$A$1 = "GiberishGiberish",
{QUERY('All'!$A$5:$AP,
"SELECT AJ, 'WCaa', 'Blah'
WHERE AJ IS NOT NULL
LABEL 'WCaa' 'BlahBlah',
'Blah' 'BlahBlahBlah'",1);
QUERY('Upload'!$A$2:$AL,
"SELECT A, 'WCaa', 'Blah'
WHERE A IS NOT NULL
LABEL 'WCaa' '',
'Blah' ''",0)} )
I tried to enclose it all in an ARRAYFORMULA, but I get the same single cell output, with no error.
What is the correct approach?
Let me know if you need dummy data, but have in mind that I have corporate security policies that restrict me from sharing any sheet to anyone outside of the company.
you will need to use IF instead of IFS like:
=IF(Validation!$A$1 = "Giberish", {QUERY(All!$A$5:$AP,
"SELECT AJ,'"&IDBlah&"','Blah'
WHERE AJ IS NOT NULL
LABEL '"&IDBlah&"''ID','Blah''BlahBlahBlah'",1)},
IF(Validation!$A$1 = "GiberishGiberish", {QUERY(All!$A$5:$AP,
"SELECT AJ,'WCaa','Blah'
WHERE AJ IS NOT NULL
LABEL 'WCaa''BlahBlah','Blah''BlahBlahBlah'",1);
QUERY(Upload!$A$2:$AL,
"SELECT A, 'WCaa','Blah'
WHERE A IS NOT NULL
LABEL 'WCaa''','Blah'''",0)}, ))
when IFS is in a combination of ARRAYFORMULA it gains a special skill which requires an array to be inputted in order to output an array again.
https://webapps.stackexchange.com/a/124685/186471

Google Sheets Query with Logic Statements

I am trying to create a list of data from a data range in Google Sheets. I thought of using the query function, but with that, you can't seem to use regular logical statements.
I know that this snippet of code is wrong and doesn't work, but hopefully it makes it clear what I'm trying to do.
=Query(E2:E103, OR(AND(D2:D103=A$2,G2:G103=A$5),AND(D2:D103=A$3,G2:G103=A$5),D2:D103=A$1))
In this code, A$2, A$5, A$3, and A$1 are all just string variables in the corresponding cells that tell the logic statement what to compare.
If there is another way to write this or a different function that accomplishes what I would like to do, it would be greatly appreciated if you could share it with me.
Basic case
The basic syntax for building a query logic:
"where F = '" & A1 & "'"
assumes A1 is a string, values in column F are strings
adds single quotes, makes the resulting query string: where F = 'sample text'
Logic
Your case looks like this:
where (A) or (B) or C =>
where (A1 and A2) or (B1 and B2) or C =>
where (D = 'text1' and G = 'text2') or (D = 'text3' and G = 'text4') or D = 'text5'

Query should exclude headers

I'm trying to get just one result from this query:
=QUERY('Registro Clinico'!A1:AA1000; "select A where(B='B12')")
where B12 contains 17.555.829-2.
I need it to return the ID of the patients, but it's returning the header name "ID".
You can exclude headers by supplying FALSE for the headers parameter. (Documentation)
=QUERY('Registro Clinico'!A1:AA1000; "select A where (E='"&B12&"')"; FALSE)
^^^^^
You had other problems as well:
The Query language does not support references into the spreadsheet in the way you had tried to write it.
"...where (B='B12')..."
Instead, you need to concatenate text segments using the & operator:
"...where (B='" & B12 & "')..."
^^^ ^^^
The column in 'Registro Clinico' that contains 17.555.829-2 is E, not B.
This should do the trick:
=QUERY('Registro Clinico'!A1:AA1000,"select A where E='" & 'Registro Clinico'!B12 & "'", FALSE)

Resources