Date and Concatenation issue with the Query function in Google Sheets - google-sheets

I am trying to make a multi client selector that can be paired with a date range. I am not getting an error and the query seems to be pulling normally but no data shows up where I know there should be.
Sheet Image:
Query Below:
=query('BH Job Data'!$A:$G, "select * where C>= date '"&text(A8,"yyyy-mm-dd")&"' AND C<= date '"&text(A10,"yyyy-mm-dd")&"' AND F = '"&$A$3&"' AND F = '"&$A$4&"' AND F = '"&$A$5&"' AND F = '"&$A$6&"'",1)
I have also tried this:
=query('BH Job Data'!$A:$G, "select * where C>= date '"&text(A8,"yyyy-mm-dd")&"' AND C<= date '"&text(A10,"yyyy-mm-dd")&"' AND F = '"&$A$3&"' OR F = '"&$A$4&"' OR F = '"&$A$5&"' OR F = '"&$A$6&"'",1)
The issue with the second string is it works fine and pull just the list of 4 clients but it does not keep the query within the intended date range.
I tried both queries above and still not getting any error. The first string pulls no results and the second string pull results from correct clients but not inside the correct date range.

You need some brackets to specify the order of operations, try this:
=query('BH Job Data'!$A:$G, "select * where C>= date '"&text(A8,"yyyy-mm-dd")&"' AND C<= date '"&text(A10,"yyyy-mm-dd")&"' AND (F = '"&$A$3&"' OR F = '"&$A$4&"' OR F = '"&$A$5&"' OR F = '"&$A$6&"')",1)
You also don't need the absolute references since this formula is not meant to be dragged.
=query('BH Job Data'!A:G, "select * where C>= date '"&text(A8,"yyyy-mm-dd")&"' AND C<= date '"&text(A10,"yyyy-mm-dd")&"' AND (F = '"&A3&"' OR F = '"&A4&"' OR F = '"&A5&"' OR F = '"&A6&"')",1)
(You could also omit select *, since it's assumed)
But if you're just filtering the data, I recommend using FILTER.
={'BH Job Data'!A1:G1;FILTER('BH Job Data'!A:G,ISBETWEEN('BH Job Data'!C:C,A8,A10),COUNTIF(A3:A6,'BH Job Data!'F:F))}

Related

Using Query to select column based on the headers

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)

How to optimize pulling multiple results of text comparison across multiple tabs in a Google Sheet? (QUERY vs FILTER vs other functions)

new as heck here and I trying to find the best way to further optimize a set of sheets functions.
The starting function was essentially 26 stacked filter functions being used to reference individual cells beneath containing names(strings), find the IDs associated with the names in these cells, pull the IDs from the "ref" sheet, and create a url that contains these IDs. The function, stripped of confidential data:
=HYPERLINK(CONCATENATE("https://url.com/stuff?ids=",if(isna(filter(ref!$B:$B,ref!$A:$A=B3))=true,"",filter(ref!$B:$B,ref!$A:$A=B3)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B4))=true,"",filter(ref!$B:$B,ref!$A:$A=B4)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B5))=true,"",filter(ref!$B:$B,ref!$A:$A=B5)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B6))=true,"",filter(ref!$B:$B,ref!$A:$A=B6)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B7))=true,"",filter(ref!$B:$B,ref!$A:$A=B7)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B8))=true,"",filter(ref!$B:$B,ref!$A:$A=B8)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B9))=true,"",filter(ref!$B:$B,ref!$A:$A=B9)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B10))=true,"",filter(ref!$B:$B,ref!$A:$A=B10)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B11))=true,"",filter(ref!$B:$B,ref!$A:$A=B11)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B12))=true,"",filter(ref!$B:$B,ref!$A:$A=B12)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B13))=true,"",filter(ref!$B:$B,ref!$A:$A=B13)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B14))=true,"",filter(ref!$B:$B,ref!$A:$A=B14)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B15))=true,"",filter(ref!$B:$B,ref!$A:$A=B15)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B16))=true,"",filter(ref!$B:$B,ref!$A:$A=B16)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B17))=true,"",filter(ref!$B:$B,ref!$A:$A=B17)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B18))=true,"",filter(ref!$B:$B,ref!$A:$A=B18)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B19))=true,"",filter(ref!$B:$B,ref!$A:$A=B19)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B20))=true,"",filter(ref!$B:$B,ref!$A:$A=B20)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B21))=true,"",filter(ref!$B:$B,ref!$A:$A=B21)),",",if(isna(filter(ref!$B:$B,ref!$A:$A=B22))=true,"",filter(ref!$B:$B,ref!$A:$A=B22)),"&morestuff=true"),"Group A")
The best I could do to optimize this was to compile the IDs in one cell (B1) with this QUERY function within a TEXTJOIN:
=TEXTJOIN(",",TRUE, QUERY(ref!$A$2:$B, "select B where A = '"&B3&"' or A = '"&B4&"' or A = '"&B5&"' or A = '"&B6&"' or A = '"&B7&"' or A = '"&B8&"' or A = '"&B9&"' or A = '"&B10&"' or A = '"&B11&"' or A = '"&B12&"' or A = '"&B13&"' or A = '"&B14&"' or A = '"&B15&"' or A = '"&B16&"' or A = '"&B17&"' or A = '"&B18&"' or A = '"&B19&"' or A = '"&B20&"' or A = '"&B21&"' or A = '"&B22&"' or A = '"&B23&"' or A = '"&B24&"' or A = '"&B25&"' or A = '"&B26&"' or A = '"&B27&"' or A = '"&B28&"' or A = '"&B29&"' "))
Then do the url generation in another cell (B2), referencing B1 for the IDs:
=HYPERLINK(CONCATENATE("https://url.com/stuff?ids=", ",", B1, "&morestuff=true"), "Group A")
I then copied these across Groups B-Z
I tried multiple variations of FILTER stacked in ARRAYFORMULA but I couldn't get it to work. I'm unsure if there is a syntax I should be using to better handle matching text that I am not quite figuring out. Simply matching by first letter is not an option as there are names that do not qualify for the groupings contained within the "ref" sheet for use in other data sets.
So my question here is really: is there an easier way to compile this where I don't have to reference each cell individually for matches on the "ref" sheet?
For an example of the sheet I am working with, this link should work:
https://docs.google.com/spreadsheets/d/1ykSldWyQnPcar9G21ljLOzm3dWC1i82kMaQJuSKHajc/edit?usp=sharing
Just use another textjoin to construct your query string as follows:
="select B"&if(counta(B3:B)=0,""," where A='")&textjoin("' or A='",true,B3:B)
Not only is this much shorter than manually typing each cell but it will also expand infinitely downward as required.

Query based on cell reference on multiple conditions on Google Sheets

I am trying to create a search function where users are able to select from a list in Google Sheets and the below query function will return that data that corresponds from the users' selections.
=query(Overview!A:AF,"SELECT D,I,M,AA WHERE AA = '"B27"' AND L ">=" "&E27&" AND S CONTAINS '"&H27&"'",1)
I expected to get the list (D, I, M, AA) but I keep getting #ERROR, what is the problem?
this is the correct syntax:
=QUERY(Overview!A:AF; "SELECT D,I,M,AA
WHERE AA = '"&B27&"'
AND L >= '"&E27&"'
AND S CONTAINS '"&H27&"'"; 1)

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'

GroupBy in F# and Average to values for each group

I am a brand new to F#, and I am having trouble with a simple first query. I have a data set, and I want to group the dollar amount based on the codes (which repeat in the data). Then, for each group I want the average (and eventually standard deviation) of the dollar amounts for each group. Also, I only want to look at ONE providerID, hence the 'where' clause. From my research, I have gotten this far:
let dc = new TypedDataContext()
let query2 = query { for x in dc.MyData do
groupBy x.Code into g
where (x.ProviderId = "some number of type string")
let average = query { for n in g do
averageBy n.DollarAmt }
select (g.Key, average) }
System.Console.WriteLine(query2)
With this I get a compiling error that says, "The namespace or module 'x' is not defined."
I do not understand this because when I ran the query that only collected the data with the specified providerID, it did not complain about this 'x', and I followed the same format with this 'x' for this larger query.
Any ideas? Thank you in advance.
From #kvb's comment: After the groupBy you can only access the group g, not the individual items x. Try putting the where before the groupBy.

Resources