Dynamic number of WHERE conditions in Google Sheet query function - google-sheets

I'm building a spreadsheet that can be used to import and then filter wireshark capture .csv's. The idea is - you import the .csv into the second tab, and on the first tab you are able to display the data based on a number of include/exclude filters. Here is a dummy sheet for reference:
https://docs.google.com/spreadsheets/d/17TtZHRiXCaH1XClq5SGRdIuyLZnMOrl6Ygrbfo9BbfM/edit?usp=sharing
As you can see in the spreadsheet, I have four possible "include" values and four possible "exclude" values, each being determined by selection of a drop down-list. The intention is for the QUERY() function in cell A6 to display the data based on these filters.
Example of the filter at work
I know how to use WHERE to do it for a single filter condition:
=query('Import CSV Here'!1:349,"select * where ("&B4&"="&B2&")")
And how to do it for multiple filter conditions:
=query('Import CSV Here'!1:349,"select * where ("&B4&"="&B2&") and ("&C4&"="&C2&")" )
What I can't figure out is how to write the QUERY function so that it only factors in a WHERE condition for filter columns that aren't blank (and therefore have been actively populated from their drop down menus). Is there an efficient way to do this?

You can wrap each filter condition in an if clause and use put something that evaluates to true if it is blank.
=query(
'Import CSV Here'!1:349,
"select * WHERE " &
IF(ISBLANK(B2), "1=1", B4 & "=" & B2) &
" and " & IF(ISBLANK(C2), "1=1", C4 & "=" & C2) )

Related

Is there a way to easily sum a few columns together, but only if the text next to them matches a dropdown selection

I've been trying to figure out what i'm doing wrong here when i'm doing the sumif formula's in b2,c2,d2
I have a lot going on, I realize. The data we are looking at, is between L5:U21
I have a query in a5 that pulls from l5:U that pairs any data in n5:n,p5:p,r5:r,t5:t to the selected data in the dropdown in a2. This part is working correctly for what I need.
B2 I am trying to extract from the top 3 options in the range b5:J that match a2, and add them together. Ultimately I'd like to do this if they do not have "Left" or "Right" in the J column as well.
To achieve this I pulled the data from b5:I into a sortn function seen in y5.
=SORTN(B5:I,3,,B5:B,false,D5:D,false,F5:F,false,H5:H,false)
and then my SUMIF function is as follows: =SUMIF(Z5:AF,A2,Y5:AE)
C2 is similar to B2, but I only data that matches the selection in a2, but also have "Left" in the J column.
I tried to achieve this with a similar SUMIF function i'm using in b2, but it seems to only pull the left most cell's data in the range given, not the matching column's data. So lets say if e9 = example1, it doesn't then grab the matching 2 in d9, it grabs whatever is in b9 only, and adds that. Which right now, it adds them all. I want to ultimately only pull the top 1, but I cannot even get it working correctly with all of them.
=SUMIF(J5:J,"Left",B5:H)
D2 is the same as C2, but "Right" in the J column.
This is my example / testing document I created to get a closer look at what's going on, if what i'm explaining isn't making a ton of sense.
https://docs.google.com/spreadsheets/d/1eZ7_yOrkoy_PCgcn_YxscPnDCvLXWK48JW-S7DqEgdQ/edit?usp=sharing
Try the following in C2
=QUERY({{B5:C;D5:E;F5:G},{J5:J;J5:J;J5:J}},
"select sum(Col1) where Col2='"&A2&"' and Col3='Left'
label sum(Col1) '' ",0)
For cell D2 all you need to do is use Col3='Right'
=QUERY({{B5:C;D5:E;F5:G},{J5:J;J5:J;J5:J}},
"select sum(Col1) where Col2='"&A2&"' and Col3='Right'
label sum(Col1) '' ",0)
In case you want to add more ranges like columns H-I you would adjust your formula like:
{{B5:C;D5:E;F5:G;H5:I},{J5:J;J5:J;J5:J;J5:J}}
(Do adjust the formula according to your ranges and locale)
SUGGESTION
I was experimenting earlier with SUMIFS & QUERY formulas to no success, as I also have a limited knowledge when it comes to implementing advanced Google Sheet formulas in a complex scenario. What I can suggest you try is by using a Custom Function formula in Google Sheet made possible by Google Apps Script that's integrated to the Google Sheet service.
This custom formula function will filter the range that does not contain Left or Right in column J based on the selected drop-down data, and then it returns the top 3 results in descending order.
The Custom formula Script named as CUSTOM_FUNC
/**
* Filters data in descending order from a range that doesn't contain any Left & Right based on selection in a cell dropdown selection & return the sum of the top 3 result.
*
* #param {B5:J21,A2} reference The range to be used.
* #returns The range and the cell reference to used in filtereing the data.
* #customfunction
*/
function CUSTOM_FUNC(data,dropdown_selection) {
/**Filter data that do not contain Left or Right on column J */
var lvl1 = data.map(x => {return x.toString().includes('Left') || x.toString().includes('Right') ? null : x }).filter(y => y)
/**Further filter lvl1 that matches the drop down selection*/
var res = lvl1.map(d => {
return d.map((find, index) => {return find == dropdown_selection ? d[index-1] : null}).filter(z => z)
});
/**Return the top 3 result in descending order */
return res.sort().reverse().slice(0, 3);
}
The parameters of this customer formula would be:
=CUSTOM_FUNC(data,dropdown_selection)
data
The sheet range (e.g. B5:J21) where the data you'd like to be processed resides.
dropdown_selection
The cell reference of the drop-down selection on your spreadsheet file.
To add this script in your spreadsheet file, copy and paste the script as a bound script in your Spreadsheet file by following this official guide
Demonstration
You can use the custom function formula named CUSTOM_FUNC similarly to how you use another Google Sheet formula on a cell, like this =SUM(CUSTOM_FUNC(B5:J21,A2))

Display COLUMN number for TRUE in rank preference list in Google Sheets

I would like the option to toggle the display of compiled rank order responses in a grid between "response indicated" and "response indicated by rank number". I'm hoping for a formula solution rather than using Apps Script.
The included screenshot displays the current and desired outcome—with current as the example for "response indicated" (link to sheet below).
The grid pulls from responses on a separate sheet as shown in the included screenshot.
NOTE:
While the choice order on the input sheet is ordered 1-5, the display grid does not list the options in sort order.
There is a sort checkbox on map!C2 that informs whether the display grid uses the same order as input or sorts alphabetically.
The display grid uses separate formulas (B4 & C4—that do not reference one another) to populate.
The closest I've been able to generate is the first row toggling to the accurate ranking (using various combinations of QUERY, VLOOKUP, INDEX, MATCH, COLUMN)—but unable to generate an array output so that each row can create a specific response.
current C1 formula (uses named ranges):
=ArrayFormula(
IF(
REGEXMATCH(
IF(autoSort,
TRANSPOSE(QUERY(
TRANSPOSE(QUERY(
QUERY(inputTable,"where A is not null order by A",0),
"select "&ARRAYFORMULA(JOIN(",","Col"&SEQUENCE(1,5,2))),)),,
COLUMNS(QUERY(
QUERY(inputTable,"where A is not null order by A",0),
"select "&ARRAYFORMULA(JOIN(",","Col"&SEQUENCE(1,5,2))),)))),
TRANSPOSE(QUERY(
TRANSPOSE(QUERY(
QUERY(inputTable,"where A is not null",0),
"select "&ARRAYFORMULA(JOIN(",","Col"&SEQUENCE(1,5,2))),)),,
COLUMNS(QUERY(
QUERY(inputTable,"where A is not null",0),
"select "&ARRAYFORMULA(JOIN(",","Col"&SEQUENCE(1,5,2))),))))),
autoOptions),
CHAR(10003),))
link to example sheet: https://docs.google.com/spreadsheets/d/1eRaRf-0n-VQ2zljqUpk38sMrFlCh19JAcv7IFMeFMw0/edit?usp=sharing
just a MattKing's mod with a checkmark switch:
=INDEX(IFNA(VLOOKUP(B4:B&C3:K3,
SPLIT(FLATTEN(input!A2:A&input!B2:F&"|"&COLUMN(input!B1:F1)-1&"|"&CHAR(10003)), "|"),
IF(C1=TRUE, 3, 2), )))
This should do it:
=ARRAYFORMULA(IFERROR(VLOOKUP(B4:B&C3:K3,SPLIT(FLATTEN(input!A2:A&input!B2:F&"|"&COLUMN(input!B1:F1)-1),"|",0,0),2,0)))

Google Sheets Query Search Box | Search criteria

so basically I have a searchbox in my sheet that searches and pulls up data. For a reference see this image: https://i.imgur.com/MVTUCSw.png. So basically in cell A4 I put the data that I am looking for, but my formula restricts me to only looking up stuff in 1 row. For example, data starting with the word MELD, but I would like to be able to also look up data based on for example the someone their name.
The formula I use for the searchbox: =QUERY({'Pallets & Locaties'!A2:G;Voorraadverschillen!A2:G}, "SELECT * WHERE Col1 "&Opzoeken!B4&" '"&A4&"'")
The data that I want to be able to look up is stored in 2 sheets: Pallets & Locaties - https://i.imgur.com/qV7h2tz.png and in Voorraadverschillen - https://i.imgur.com/foqLkKa.png.
The searchbox is only able to lookup data in row, but I just want to be able to search for any kind of stored data in any of the sheets.
Here is my sheet for reference: https://docs.google.com/spreadsheets/d/10wmnxV16JUiD_b_54abkiLPwTqLITWRcUw3gsqvXoBE/edit?usp=sharing
I'd recommend you add more rows for the lookup criteria and add a column for what column it would search for.
Sheet modification:
Formula:
=QUERY({'Pallets & Locaties'!A2:G;Voorraadverschillen!A2:G}, "SELECT * WHERE "&TEXTJOIN(" AND ", TRUE, ARRAYFORMULA(IF(ISBLANK(A4:A10), "", A4:A10&" "&B4:B10&" '"&C4:C10&"'"))))
Test Sheet
Note:
The above formula will allow you to search on other columns with their own words and criteria to search.
Only rows with Kolom values will be included in the criteria. If you only need Col1 criteria, make sure to leave other rows blank.
This does use an AND search, meaning all of the criteria should be true and match the row. Feel free to use OR in the TEXTJOIN function if you only want to search all rows matching any of the criteria.
This will only search on sheets Pallets & Locaties and Voorraadverschillen. Add the necessary sheets if you need them.
EDIT:
Cleaned up the formula to not be so repetitive.
=IF(A4<>"",(QUERY({'Pallets & Locaties'!A2:G;Voorraadverschillen!A2:G},"Select * WHERE "&textjoin(" OR ", true, arrayformula("Col"&ROW(1:7)&" "&B4&" '"&A4&"'")))),(QUERY({'Pallets & Locaties'!A2:G;Voorraadverschillen!A2:G},"Select * WHERE Col1 IS NOT NULL")))
This searches every column for the data, as long as data is not identical in two columns you won't have issues. An example would be the search criteria "MELD" being in both Column A and B. If that were the case, only the results from the first matching column would populate.

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)

Data reduction via IMPORTRANGE

I am trying to do some data reduction in my Google Sheets by using the following IMPORTRANGE formula:
=query(importrange("https://docs.google.com/a/ap.averydennison.com/spreadsheets/d/1xz1lXY-w5Ii_aWqVAhHgRCmeoes9ltSUtibE4kzhMHA/edit#gid=2051232966","SF_Flex_Rel!a:l"),
"select * where Col1 = '"&text(B1,"###")&"'",1)
The 'source' sheet has a whole lot of sales data records. What I am trying to do in the new sheet via this formula is only bring in the sales records from the source sheet that match the customer number specified in cell B1.
It seems to work OK if I limit the IMPORTRANGE to only query about 10,000 rows. Once I go over around 20,000 rows the screen will briefly flash up the records, then a small progress bar shows in the top right corner of the sheet and the records disappear. The cell with the formula just shows #ERROR! with no other comments to tell me why.
Is there something wrong with my formula syntax?
Is there a better way to achieve this data reduction?
Is there some undocumented data limitation on IMPORTRANGE function (I am using 'new' Google Sheets)?
try like my example :
=QUERY( // data
IMPORTRANGE(
"Spreadsheet Key", // spreadsheet key
"DATA!A:C" // datarange
),
"SELECT Col1 WHERE Col2=" & "'" & B2 & "'" // query
)
I had the same problem. This answer helped me find a workaround : https://productforums.google.com/forum/#!topic/docs/RxVUFGWQ2Y4
In my example :
1) In the spreadsheet where the data is I have added a few empty columns (E to H) in order to display 4 columns of data in 5 maximum rows.
=Query(Sheet1!A:D,"select * Where A contains 'KEYWORD' limit 5",1)
2) Then in the other spreadsheet:
=ImportRange("https://docs.google.com/spreadsheets/d/ss_key_here/", "'Sheet1'!E1:H5")

Resources