How to refer to column 'BY' in query? - google-sheets

In my Google spreadsheet, i'm using the query function to get data from one sheet onto another. The query looks something like this:
=QUERY('mySheet'!$A$1:100,"select F where "&C$3&"='myValue'")
This works fine until cell C3 has value "BY" (because the word "by" has significance in the query language). I've tried using single quotes, but then the query uses header "BY" instead of column BY and it returns an empty result.
Any ideas on how to work around this?

Put it in backticks.
=sum(QUERY(select `BY` where `BY` is not null limit 7))
This will sum the first 7 values in column BY.
(This was fun to debug. The formula worked in every other column...)

"BY" is a special word. It is present in clause group by
You may use this:
=QUERY({'mySheet'!$A$1:100},"select Col5 where Col"&C$3&"='myValue'", 0)
and paste the column number into C$3
see more info here
BTW you may use function column() to know BY is column 77 or find the right number by header name: =match("column name", 'mySheet'!1:1, 0)

Related

Google Sheets QUERY Function: Select Columns by Name

I have a Google Sheet with named ranges that extend beyond columns A-Z. The name ranges have header rows. I would like to use the QUERY function to select columns by their header labels.
My formula is like this:
=QUERY(NamedRange,"SELECT AZ, AX, BM where BB='student' ORDER BY BM DESC",1)
Answers to other questions on StackOverflow, like that accepted here, haven't worked. Another answer found here on Google's support page doesn't work for columns beyond Z.
How can I use the QUERY function and select columns beyond column AA by their header labels?
DESIRED OUTPUT / SAMPLE DATA
A sample spreadsheet with desired output can be found here.
you can transpose it and header row becomes a column. then:
=TRANSPOSE(QUERY(TRANSPOSE(A1:C), "where Col1 matches 'bb header|student'", ))
where A1:C is your named range (including header row)
update:
=QUERY({AI1:AK6}, "select Col2,Col3 where Col1='Jones'", 1)
dynamically:
=LAMBDA(p, t, s, QUERY({AI1:AK6},
"select Col"&t&",Col"&s&"
where Col"&p&"='Jones'
order by Col"&t&" desc", 1))
(MATCH("principal", AI1:AK1, ),
MATCH("teacher", AI1:AK1, ),
MATCH("student", AI1:AK1, ))
WHY LAMBDA ?
LAMBDA is a regular GS function that allows substituting any type of ranges with custom strings. generic example of simple lambda: =LAMBDA(x, x+5)(A1) which is in old terms: =A1+5 therefore you can understand it as x being a placeholder for A1. one more example: =IF((A1+1)>(B1+1), B1+1-A1+200, B1+1*A1+20) contains a lot of repeating cell references so we can refactor it like: =LAMBDA(a, b, IF((a+1)>b, b-a+200, b*a+20))(A1, B1+1) this comes especially handy with more advanced formula stacking when instead of repeating the whole fx multiple times we can wrap it in Lambda to shorten it and make it cleaner
you can have as many LAMBDAs as you wish:
here, just for fun, one more example... with lambda:
and without lambda: pastebin.com/raw/BREgC9La
(from: stackoverflow.com/a/74380299/5632629)
You can try the below Named Function I created a while ago. Import from here
Name
_BETTERQUERY
Usage example
=_BETTERQUERY(A1:C10,"select `name` where `age` > 18",1)
Formula description
Runs a Google Visualization API Query Language query across data. It supports the usage of column headers.
Argument placeholders
range
better_query
headers
Formula definition
=QUERY({range},REGEXREPLACE(REDUCE(better_query,
REGEXEXTRACT(better_query,REGEXREPLACE(REGEXREPLACE(better_query,
"([()\[\]{}|^.+*$?])","\\$1"),"`(.*?)`","`($1)`")),LAMBDA(acc,cur,
SUBSTITUTE(acc,cur,"Col"&MATCH(cur,ARRAY_CONSTRAIN(range,1,9^9),0),1))),
"`(Col\d+)`","$1"),headers)
Notes
This function is built on top of QUERY, so you can use it exactly as QUERY. When referring to the columns with their header, make sure that the first row of range is the header and in better_query enclose the column header between two backticks `col_header`. (See example usage above)
The headers parameter is not optional since Named Functions do not currently allow optional parameters.
If you want to understand more about how this works. See How to Use Column Names in QUERY

Google Sheets Query Coalesce?

is there any query syntax that woks like coalesce in google sheets?
if i have a source like pict below
the result i want is only getting id and time if status is true, but the time is only exist in one col either in check column or report column
so the result would be like this...
I tired this but doesn't work
=QUERY(A1:D4, "SELECT A, COALESCE(B, C) WHERE D = TRUE")
any ideas or workarounds?
Thanks
try:
=ARRAYFORMULA(IFERROR(SPLIT(FLATTEN(QUERY(TRANSPOSE(
ARRAY_CONSTRAIN(IF(D2:D=TRUE, {A2:A, IF(B2:C="",,"×"&B2:C), D2:D}, ), 9^9,
COLUMNS(A:C))),, 9^9)), "×")))
A very short one just for the special case of 2 columns where you know that only one of them is populated and they are dates:
=ArrayFormula(to_date(if(D2:D,B2:B+C2:C,)))
Maybe the simplest formula which behaves like coalesce would be
=iferror(if(D2,hlookup(9^9,B2:C2,1,true),))
It's just a pull-down formula but will pick up the first non-blank column from a range of columns containing numbers or dates. If the columns are all blank, it returns blank.
You can take advantage of the either or situation and concatenate the 2 columns.
=filter({A2:A,concat(B2:B,C2:C)},D2:D)
Also see local array and filter
Add a column after Status call it Time (column E), whereas each formula follows this format (assuming your table starts at A3:E)
=if(A4="","",if(B4<>"",B4,C4))
Now query A3:E like so,
=query(A3:E,"Select A,E where D=TRUE")
you can use something like this:
=QUERY(transpose(B1:H1),"Select Col1 where Col1 is not null limit 1",0)
This transposes the row into a column, queries all non-null values from that column, and then set limit 1 to return the first value. So essentially you are selecting the leftmost non-empty value from your row.
I can't take full credit for this, I must have gotten it somewhere else... but it's in one of my sheets.

Fetching data from other Spreadsheet by comparing some values

I have a sample Spreadsheet such as
And I want to import data from this spreadsheet to another spreadsheet, but after comparing some data, such as
My noob formula for the selected cell name in the second image:
=Query(ImportRange("URL of first spreadsheet","sheet!B:D"),"Select Col2 where Col2=A.....(what to add here? this column 'A' is not working for comparing the names)
My Approach:
I will compare the values from the import range with the existing column i.e. previousSpreadsheet.name.A=thisSpreadsheet.this_name.A and compare every name and SELECT values accordingly for the next three columns (in yellow). I hope I'm clear.
What should I add here? Is my approach right? If not, What are the alternatives to achieve this?
Thanks.
EDIT
(following OP's request)
Also, can I compare two cols with one? such as where LOWER(Col2)='"&LOWER(A2)&"' or '"&F2&"' or Col2=A2 || F2 something like this? for comparing two cols with one?
If you start using more than one names as variables, you may want to consider using other alternatives for the where clause, like matches
=Query(ImportRange("URL of first spreadsheet","sheet!B:D"),
"Select Col2 where Lower(Col2) matches'"&LOWER({A2&"|"&F2})&"'")
Original answer
Please use
=Query(ImportRange("URL of first spreadsheet","sheet!B:D"),"Select Col2 where Col2='"&A2&"'")
(where A2 is the name you need)
Pay notice to the syntax referring the cell: single quotes ' double quotes" ampersand & cell A2 and again &"'.
No spaces in between
try:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A, IMPORTRANGE("ID", "sheet!B:D"), {1,2,3}, 0)))

How to use substitute function with query function in google spreadsheet

I am trying to use substitute function inside a query function but not able to find the correct syntax to do that. My use case is as follows.
I have two columns Name and Salary. Values in these columns have comas ',' in them. I want to import these two columns to a new spreadsheet but replace comas in "Salary" column with empty string and retain comas in "Name" column. I also want to apply value function to "Salary" column after removing comas to do number formatting.
I tried with the following code but it is replacing comas in both the columns. I want a code which can apply the substitute function only to a subset of columns.
Code:
=arrayformula(SUBSTITUTE(QUERY(IMPORTRANGE(Address,"Sheet1!A2:B5"),"Select *"),",",""))
Result:
Converted v/s Expected Result
Note :
I have almost 10 columns to import and comas should be removed from 3 of them.
Based on your suggestions, I was able to achieve the objective by treating columns separately. Below is the code.
=QUERY({IMPORTRANGE(Address,"Sheet1!A3:A5"),arrayformula(VALUE(SUBSTITUTE(IMPORTRANGE(Address,"Sheet1!B3:B5"),",","")))},"Select * where Col2 is not null")
Basically, two IMPORTRANGE functions side by side for each column.
The same query on the actual data with 10 columns will look like this.
=QUERY({IMPORTRANGE(Address,"Sheet1!A3:C"),arrayformula(VALUE(SUBSTITUTE(IMPORTRANGE(Address,"Sheet1!D3:H"),",",""))),IMPORTRANGE(Address,"Sheet1!I3:J")},"Select * where Col2 is not null")
I used 3 IMPORTRANGE functions so that I can format the columns D to H by removing comas and changing them to number.
My suggestion is to use 2 formulas and more space in your sheets.
Formula #1: get the data and replace commas:
=arrayformula(SUBSTITUTE(IMPORTRANGE(Address,"Sheet1!A2:B5"),",",""))
Formula #2: to convert text into numbers:
=arrayformula (range_of_text_to_convert * 1)
Notes:
using 2 formulas will need extra space, but will speed up formulas (importrange is slow)
the second formula uses math operation (*1) which is the same as value formula.
Try this. I treats the columns separately.
=arrayformula(QUERY({Sheet1!A2:A5,SUBSTITUTE(Sheet1!B2:B5,",","")},"Select *"))
Thanks to Ed Nelson, I was able to figure out this:
=arrayformula(QUERY({'Accepted Connections'!A:R,SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE('Accepted Connections'!A:R,"AIF®",""),"APA",""),"APMA®",""),"ASA",""),"C(k)P®",""),"C(k)PS",""),"CAIA",""),"CBA",""),"CBI",""),"CCIM",""),"","")},"Select *"))
That removed all the text I didn't need in specific columns.

pulling row number into query google spreadsheet

I have a data set that looks like this: starting on A1 with "1"
1 a
2 b
3 c
4 d
Column A is an arrayformula =arrayformula(row(b1:b))
Column B is manual input
i want to query the database and finding the row of the item by match column B so i have code as such
=query("A1:B","select A where B like '%c%')
this should give me "3"
My question:
is there a way to pull the 1-4 numbers into the query line? with something like array formula row(b1:b). I don't want to waste an extra column on column A
so basically I want just the manual input and when i query it gives me the row number.
No script code please.
I've tried a few things and it didn't work.
Looking for a solutions that starts with
=query()
You can also use a formula to pull in more than one row in the dataset which matches the condition, if this is important to you:
=arrayformula(filter(row(B:B); B:B="c"))
And you can have wildcard type operators, under certain circumstances (you are going to match text or items that can look like text (so numbers can be treated as text - but boolean will need more steps); that the dataset is not huge), using regular expressions. e.g.
=arrayformula(filter(row(B:B); regexmatch(B:B, "(c|d)")))
You could also use standard spreadsheet wildcard operators, e.g.
=arrayformula(filter(row(B:B); countif(B:B, "*c*")))
Explanation: In this case, the filter will be true when countif is greater than zero, i.e. when it sees something with a letter c in it, since spreadsheets see a value greater than zero as a boolean true and so, for that row where there is a countif match, there will be a a filter match, and so it will display that row (indeed, it is a similar situation with the regexmatch creating a true when there is a match of either c or d, in the case above).
Personally, I wanted to learn regex a bit, so I would go towards the regexmatch option. But that is your choice.
You can also, of course, create the match outside of the cell. This makes it easy to create a list of matches that you want to satisfy elsewhere on the sheet. So you could have a column of words or parts of words, from Z2 downwards, and then join them together in cell Z1 for example like this
="("&join("|",filter(Z2:Z50,len(Z2:Z50)))&")"
Then your filter function would look like this:
=arrayformula(filter(row(B:B), regexmatch(B:B, Z1)))
If you want to use like operator in the query function, you can try something like this:
=arrayformula(query(if({1,0}, B:B,row(B:B)),"select Col2 where Col1 like '%c%' "))
You can also use the regular expressions in the query function, for example:
=arrayformula(query(if({1,0}, B:B,row(B:B)),"select Col2 where Col1 matches '(.*c.*|.*d.*)' "))
I'm not entirely clear on the question, but as I understand it, you want to be able to enter a formula, and have it return the row number of the matched item in a range? I'm not sure where array formulas come in.
If I've understood your question correctly, this should do the trick:
=MATCH("C",B1:B,0)
In your example, this returns 3.
Please forgive me if I've misunderstood your question.
Note: If there are multiple matches, this will return the row number for the first instance of your search.
=QUERY({A1:A,ARRAYFORMULA(ROW(A1:A))},"SELECT Col2 WHERE Col1 LIKE '%c%'")

Resources