QUERY using cell contents as SQL variables - google-sheets

Here is what the spreadsheet I'm working with looks like:
Summary table
(top of sheet)
Source data
(same sheet, below output)
I'm using the QUERY function to populate the appropriate feeds in the summary table with the data starting at A24 needs to be placed into.
Here is the formula I'm using in cell C6 (similar formulas are used throughout the summary table):
=QUERY($A$24:$D$57, "Select D Where B='ENQ' and A='2/27/14 - Thu'")
This gets the right information, but the formula needs to be edited to be unique in each cell it's used in. The problem being unable to quickly populate the cells with A='2/27/14 - Thu' being too specific.
I was trying to set it up so that:
date in A would compare with dates found on headers in ROW 2 before accepting data
room type in B would compare with value from A in each row of the summary table
How can the QUERY function be written to refer to these values as variables, instead of using the literal strings in my original function?

Instead of fixed strings such as 'ENQ', you can have your formula refer to the index in column A of your output. For example, you could change your formula to this, in cell C4:
=QUERY($A$24:$D, "Select D Where B='" & $A4 & "' and A='2/27/14 - Thu'")
^^^^^^^
The ampersand (&) is used to concatenate string segments.
Note that since the source data extends to the bottom of the data range of the sheet, we can forego specifying the bottom row. The range $A$24:$D will take in all rows, so it will automatically adjust to additional source data.
To compare dates, both values need to be dates. "2/27/14 - Thu" is not recognized as a date in your source data sheet, but as text, even though you've set the numeric format to date. So make sure you change all your source data to have actual dates in column A.
You can still have your dates formatted the way you like - see this screenshot. The content of A2 is now a proper date, "2/27/2014", but the format is set to display "mm/dd/yy - DDD". As long as the data is a date, the query can be built using the spreadsheet TEXT function to interpret the date in its yyyy-mm-dd format.
With dates in your source column, you can use todate() scalar function to tell QUERY to convert the date in the source to a query-date, and the date keyword to treat the following literal string (from C2) as a date.
The resulting function for cell C4 is:
=QUERY($A$24:$D , "Select D Where B='" & $A4 & "'and todate(A) = date '" & TEXT($C$2,"yyyy-MM-dd") & "'")
^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Similarly, for D4:
=QUERY($A$24:$D , "Select C Where B='"&$A4&"'and todate(A) = date '"&TEXT($C$2,"yyyy-MM-dd")&"'")
Your calculations in column E can be improved to handle #N/A results appearing in columns C or D:
=if(isna(C12*D12),0,C12*D12)

Related

Google Sheets Query with Variables in the data section

I am trying to create a health related spreadsheet that has a lot of data - a lot of which isn't relevant to this question so I've simplified it. There is a column for each type of pain where you write on a scale of 0-10 how intense your pain was, and another column for any relevant notes. The data is broken up into named ranges to make it easier to display on different tabs (HeadData = Head Pain, ChestData = Chest Pain, etc. - 15 named ranges in total.)
One of the tabs I'm working on has a table where you are viewing only the specific named range, in this case HeadData.
=query({HeadData}, " Select * where Col1 is not null ",1)
This works perfectly, but I want to replace {HeadData} with a reference cell to a drop menu so you can select the specific pain area column you want to be displayed.
If I put the reference cell in G1 with a drop down list of the named ranges and select ChestData and try to do
=query({&G1&}, " Select * where Col1 is not null ",1)
It is only picking up G1 (ChestData) as a string and not the actual named range.
So my question is, is there a way to make a drop menu containing named ranges that turn into actual sets of data and not strings when placed in the data section of the query?
Here is my spreadsheet, any help is appreciated. Thanks!
https://docs.google.com/spreadsheets/d/1CcuSV2bbfxsUPPkmj-fru2yYYmmtpXk9LKEF85sxVUw/edit?usp=sharing
You can use INDIRECT for this.
INDIRECT
Returns a cell reference specified by a string.
Change your formula to
=query({INDIRECT(G1)}, " Select * where Col1 is not null ",1)
The INDIRECT function will convert the string in G1 to a cell reference and then the rest of your formula will query the relevant named range.

vlookup a value and return if it is after a certain date

Hello I Have a sheet with a list of names, medications, statuses and correlating dates on a spreadsheet. On a separate spreadsheet I would like to be able to type in a date and status (ex. "Pending", "active") and have the correlating patient names come up.
If i Type in 5/6/21 and then "active" I would like the formula to search the master-sheet and return names of patients whos status is "Active" after the Date 5/6/21.
I can't open your second sheet, but based on the first one, I've added a date input in cell F2.
Sheets QUERY is a powerful function that is similar to SQL. It can be used to display data from a dataset based on certain parameters (like your date search, and status = active).
In the example, the following QUERY formula goes in cell H1, but you can move it to a different tab if needed, obviously referencing 'DATA'!A:E etc.
=if(isblank(F2),,iferror(query(A:E,"where D > date '"&text(F2,"yyyy-mm-dd")&"' and lower(E) contains 'active' order by D,A",1),"No result"))
functions
isblank - if cell F2 is blank (the date search), then nothing.
iferror - if the query doesn't return any values, just output the wording 'No result'.
query function - as per the parameters below.
The range of your data is cells A:E.
The where clause basically says that the value in col D needs to be greater than the date within the single quotes '', which contains "&text(F2,"yyyy-mm-dd")&", which is the value of cell F2, formatted as text in the structure yyy-mmm-dd.
Placing "&<Sheets function>&" within the single quotes '' allows you to put another Sheets function in the query syntax, in this example the text function that formats the input of cell F2 as a date yyyy-mm-dd.
The where clause also includes an and where the lowercase of column E, lower(E) contains the word 'active'.
The results are ordered by column D then column A.
The ,1 at the end of the query tells it to treat the first row of data as headings. If it was data and not a heading, then it would be ,0.
Let me know if you need it implementing on your actual sheet.

Google Sheets' dynamic data range in query function

is it possible to have a dynamic data range when using query function in Google sheet?
What I would like to do is, using a dropbox, change the data range used in query function.
For example, I have 4 tables in 4 different sheets. On my main sheet, I want using my dropbox, perform a query on my selected table.
Is it necessary to do it with a script?
You can make a dynamic query without using a script.
The query string can contain a reference to other cells.
Example in Sheets.
This example has a pulldown for the data set in B2, a pulldown for the value set in B4. The data ranges include one from another sheet. I am using named ranges to simplify the lookup process. Each data set n is named DataN.
You can separate out the query string from the cell with the actual query function call. The trick is to build up a query string using INDIRECT, COLUMN, and VALUE. I placed this in cell A10:
="select " & mid("ABCDEFGH",COLUMN(INDIRECT(B2)),1) & " where " & mid("ABCDEFGH",VALUE(COLUMN(INDIRECT(B2)))+1,1) & "=" & """" & B4 & """"
The four quotes let us place a literal quote in the query string. The '&' character does string concatenation.
The use of MID as a way of translating the COLUMN function to a letter I got from here.
Then your cell with the query uses the values of the data set pulldown (B2) and the value of the query string (A10) this like:
=QUERY(INDIRECT(B2),A10,1)

Google Sheets: Query function can't copy data

I attached a sample Google Sheet data (Link).
It contains 2 sheets. The Response sheet contains the response of the Google Form. Since the Google form has a lot of repeating questions, I have to transform the data using the Query function (sheet Transformed cell B2). The query command is
=QUERY(
{
Response!E2:H,Response!B2:D;
Response!I2:L,Response!B2:D;
Response!M2:P,Response!B2:D;
Response!Q2:T,Response!B2:D;
Response!U2:X,Response!B2:D;
Response!Z2:AC,Response!B2:D;
Response!AD2:AG,Response!B2:D;
Response!AH2:AK,Response!B2:D;
Response!AL2:AO,Response!B2:D;
Response!AP2:AS,Response!B2:D;
Response!AU2:AX,Response!B2:D;
Response!AY2:BB,Response!B2:D;
Response!BC2:BF,Response!B2:D;
Response!BG2:BJ,Response!B2:D;
Response!BK2:BN,Response!B2:D;
Response!BP2:BS,Response!B2:D;
Response!BT2:BW,Response!B2:D;
Response!BX2:CA,Response!B2:D;
Response!CB2:CE,Response!B2:D;
Response!CF2:CI,Response!B2:D;
Response!CK2:CN,Response!B2:D;
Response!CO2:CR,Response!B2:D;
Response!CS2:CV,Response!B2:D;
Response!CW2:CZ,Response!B2:D;
Response!DA2:DD,Response!B2:D
},
"select * where Col1 <> '' Order By Col6"
)
However when you look at the sheet Transformed, some data in Col F (Corresponding to Response sheet Col B) didn't get transferred. How could this problem be fixed?
Thanks in advance
It is often noted that users are tempted to mix data types within a column. The query() function will give undesirable output. If a column is intended for numeric values then only numerical values must reside in that column. Date columns must only contain dates and text columns only contain text values.
This does not mean that numbers cannot appear in a text column as long as they are in a text format.
Generally, the query() function will assume the greater number of cell types in a column to be that data type. For example, if there are 100 numbers and 20 text values in the same column then a numeric value will be assumed for that column. There is a good chance the text values will just be ignored. A slight change in your formula will convert all values to text.
See if this helps
=ArrayFormula(QUERY(to_text({
Response!E2:H,Response!B2:D;
Response!I2:L,Response!B2:D;
Response!M2:P,Response!B2:D;
Response!Q2:T,Response!B2:D;
Response!U2:X,Response!B2:D;
Response!Z2:AC,Response!B2:D;
Response!AD2:AG,Response!B2:D;
Response!AH2:AK,Response!B2:D;
Response!AL2:AO,Response!B2:D;
Response!AP2:AS,Response!B2:D;
Response!AU2:AX,Response!B2:D;
Response!AY2:BB,Response!B2:D;
Response!BC2:BF,Response!B2:D;
Response!BG2:BJ,Response!B2:D;
Response!BK2:BN,Response!B2:D;
Response!BP2:BS,Response!B2:D;
Response!BT2:BW,Response!B2:D;
Response!BX2:CA,Response!B2:D;
Response!CB2:CE,Response!B2:D;
Response!CF2:CI,Response!B2:D;
Response!CK2:CN,Response!B2:D;
Response!CO2:CR,Response!B2:D;
Response!CS2:CV,Response!B2:D;
Response!CW2:CZ,Response!B2:D;
Response!DA2:DD,Response!B2:D}),"select * where Col1 <> '' Order By Col6"))

Google sheets conditional formatting based on =QUERY result

I am trying to conditionally format a row in Google Sheets based on the result of a QUERY operation. I can get the QUERY to return the value I want (either 0 or non-zero), however QUERY insists on returning a header row.
Since the QUERY now takes up 2 rows for every row of data, changing the format of the row based off the QUERY result starts to get weird after just a few rows.
The problem I am ultimately trying to solve in the case where I enter a list of names, and I want to compare each name to a list of "NSF Names". If a name is entered, and it exists on the NSF list, I would like to flag the entry by highlighting the row red.
Help is greatly appreciated.
Edit: Formula, as requested:
=query(A:D,"select count(A) where C contains '"&E1&"' and D contains '"&E2&"'")
A:D is the data set (A is a numeric ID, B is full name, C and D are first and last names respectively).
E1 and E2 are placeholders for the person's first and last name, but would eventually be replaced with parsing the person's name, as it's inputted on the sheet (TRIM(LEFT(" ", A2) etc...)
I can get the QUERY to return the value I want (either 0 or non-zero),
however QUERY insists on returning a header row.
There might be better ways to achieve what you want to do, but in answer to this quote:
=QUERY(A:D,"select count(A) where C contains '"&E1&"' and D contains '"&E2&"' label count(A) ''")
A query seems a long-winded approach (=countifs(C1:C7,E$1,D1:D7,E$2) might be adequate) but the label might be trimmed off it by wrapping the query in:
index(...,2)

Resources