Question: In Google Sheets, using only the built-in functions, how do I write a filter to exclude records based on a column in each row not being present in a list of valid values from another range.
Details
I am using Google Sheets to write a finance spreadsheet where all of my expenses and incomes are entered into a single sheet called Transactions. I have a separate sheet called Constants where I keep a list of income categories and a list of expense categories.
Here is some sample data for purposes of the question:
Constants
Transactions
I have a sheet called ByMonth where I want to show all of the expense transactions in one section and all of the income transactions in a separate section.
Goal:
I need to essentially do this sql query in google sheets functions:
select date, category, amount from transactions
where category not in (
select * from expense_categories
)
but I cannot figure out how to get Google Sheets to let me do an IN concept with their functions.
Here is a cell function expression that I am using for filtering the rows based on a date field:
=filter(Transactions!A2:C,
DATEVALUE(Transactions!A2:A) >= date(2015,4,1),
DATEVALUE(Transactions!A2:A) <= date(2015,4,30)
)
I would be adding a third condition to the filter() function, and that third condition would somehow compare the Category column of each row of data against the list of valid expense or income categories and return a boolean.
Here are some other things that I have tried, to no avail, including some variations of MATCH, ARRAYFORMULA, etc:
=filter(Transactions!A2:C, row(Transactions!B2:B) = UNIQUE(Constants!A2:A))
=filter(Transactions!A2:C, Transactions!B2:B = UNIQUE(Constants!A2:A))
=filter(Transactions!A2:C, Transactions!B2:B = Constants!A2:A)
Any suggestions?
The formula you are interested in is:
=filter(Journal!A2:C13,IFERROR(Match(Journal!B2:B13,Categories!A2:A3,0)))
The function match(a, b, 0) searches if a can be found in b. You need 0 at the end for exact match (default is closest match). If a cannot be found, you get an error, so you wrap the function with iferror to skip error.
Here is working example file
As each category use a keyword, expense or income, the following formulas return the desired results
=query(Journal!A2:C13,"Select * where B contains 'expense'")
=query(Journal!A2:C13,"Select * where B contains 'income'")
Related
[Goal]
I want to be able to count unique values that are present in 2 different sheets only if they exist in both sheets.
[Details]
First, there are 2 sample data sheets (Data A, Data B) within the same Spreadsheet and it also has a sample dashboard to do the calculations. One thing to note about the data sheets is that they have different ranges, so they have different number of columns and rows. However, a couple things they have in common are the Month and ID columns.
Next, in the Dashboard sheet, there are 3 cells where B3 is the Month selector, C3 is to count the number of unique IDs that are included in both sheets (Data A & Data B) based on the month. With D3, I would like to count the number of unique IDs that are included in both sheets (Data A & Data B) where the the Month are the same AND Data B sheet's Cumulative column is 1.
[What I tried so far]
I tried using the COUNTUNIQUEIFS function and had the range as an array (by using the curly bracket) in the below way, however, it didn't work.
=COUNTUNIQUEIFS('Data A'!$B:$B,'Data A'!$A:$A,B3,'Data B'!$A:$A,B3)
I also tried without making the range argument an array.
=COUNTUNIQUEIFS('Data A'!$B:$B,'Data B'!$A:$A,B3)
Both attempts results in 1 for February 2023 when it should return 2. The weird thing is that January 2023 should return 3 and it correctly returns 3.
Hope someone can help me out with this. If there's a more elegant solution to achieve this by using Google Apps Scripts, I'd like to see hear about that as well.
You can try filtering both ranges for month, and the FILTER again by comparing them with MATCH and counting the remaining results:
=LAMBDA(ar,br,COUNTA(IFERROR(FILTER(ar,NOT(ISERROR (MATCH(ar,br,0))))))
(FILTER('Data A'!B:B,'Data )A'!A:A=B3),FILTER('Data B'!B:B,'Data B'!A:A=B3))
And just add an additional filter for the next column and the cumulative =1 'Data B'!C:C=1
=LAMBDA(ar,br,COUNTA(IFERROR(FILTER(ar,NOT(ISERROR (MATCH(ar,br,0)))))) (FILTER('Data A'!B:B,'Data )A'!A:A=B3),FILTER('Data B'!B:B,'Data B'!A:A=B3,'Data B'!C:C=1))
I have a problem writing down a formula or a script in Google Sheet or Google App Script to find and count the values in a sheet where the number and references to the columns change.
I have a script that copy&paste the Sheet files for the staff shifts of every week from a Drive folder and merge them side by side (in horizontal).
In this sheet that contains all the shifts merged I want to count all the cells of the staff filtered only for handler and picker (column B, K, etc.) according to a specific date (row 3) for every hour.
Example: if today is 28/10/2020 find the right column with the same date in row 3 --> column E, count all the values from row 4 filtered by picker or handler for every hour (10 people at 05 AM).
Do you think that I can implement this with a formula (like a matrix, vlookup, etc.) or should it be written as a Script?
Thank you very much,
Marco
Please use the following
=COUNTA(QUERY({A3:I;J3:R},"select Col"&MATCH(A1,A3:I3)&"
where Col2 matches 'Technician|Picker' "))
Where B1 holds the date you wish to search for (28/10/2010)
Try the below formula. Replace date with your search date.
=COUNTA(INDEX(A4:R14,,MATCH(DATE(2020,10,28),A3:R3)))
This was earlier tagged as excel. This is how to "tackle" this in excel (office 365):
In a clear column use the following formula to get the unique hour-values that are in the column that equal today:
=UNIQUE(FILTER(INDEX(($4:$1048576,,MATCH(TODAY(),$3:$3,0)),INDEX(($4:$1048576,,MATCH(TODAY(),$3:$3,0))<>""))
In the column next to that type the following to get the result of the count of those unique values for that day:
=COUNTIF(INDEX(($4:$1048576,,MATCH(TODAY(),$3:$3,0)), FILTER (I:I,I:I<>""))
Where I:I in FILTER (I:I,I:I<>"") needs to be changed into the column you put the first formula.
I have a new google sheet set up to query my database via a connected sheet.
The query returns a list of our shops and their sales per year. Each shop has an ID.
I am able to set Cell A1 in another, reference sheet, to be a parameter in the query. This way the connected query only returns results for that particular store ID.
When using this, I really want to put an IN function into my query. The connected query would then look something like.
SELECT * FROM shops where shops.id in (#RANGE)
And #RANGE would be A2:A as an array.
I've had success naming each cell as a new parameter and then:
SELECT * FROM shops where shops.id in (#REFERENCE1, #REFERENCE2)
Is there a more elegant solution?
Maybe a little late, but the easiest way I found was to convert to regex.
select (#POSTCODES) as test, postcode
from `postcode.au_towns`
where regexp_contains(#postcodes,safe_cast(postcode as string))
Where #POSTCODES is a gsheet string using a formula like join("|",UNIQUE(Sheet1!D2:D)).
Just make sure to remove the extra "|" generated using something like
left(B2,len(B2)-1)
This might work for you.
=SUBSTITUTE(QUERY(FILTER(D3:D,D3:D<>"",E3:E),"WHERE Col1 <> ''",9^99)," ","|")
This filters a column of store IDs based on which ones have been selected, and coverts that into a text string similar to the query you have been using. Producing something like "A1|A3|A7".
The query then just points to that result for the contains criteria.
Note that if your range of store IDs to report on is built in some other fashion, you just need to point to its range, instead of using the filter I have.
See a sample sheet here. This also shows a merged example of the two formulas, to produce the report all from one formula.
https://docs.google.com/spreadsheets/d/11uMa7CNcTXBnnpWGSIC_WvGSa-P2GTLQ2T7GvTgY4oM/edit?usp=sharing
Let us know if this helps you.
=QUERY(IMPORTRANGE("Google_Sheet_ID_Can_Be_Find_In_URL", "Sheet_Name!Range(you want to query)"),"SELECT * ")
or
=QUERY(IMPORTRANGE("Google_Sheet_ID_Can_Be_Find_In_URL", "Sheet_Name!A2:A"),"SELECT * ")
or
=QUERY(IMPORTRANGE("Google_Sheet_ID_Can_Be_Find_In_URL", "Sheet_Name!Range"),"SELECT * WHERE Col2='shops.id'")")
IMPORTRANGE() method import data from another worksheet. In the parameter, you type google sheet id from the url with quotes, type the desired sheet name end with ! Then you type the range from that sheet you want to query. When you wrap it with the outer QUERY() method, you can query the data from that range such as A2:A by selecting specific columns including the column with the range or * from that sheet name
When you're using IMPORTRANGE() method, it's going to return an array. The selected columns have to label in numeric like "SELECT Col 1, Col 2, Col 3"
I have found numerous examples online to use SUMIF and SUMIFS statements in Excel when comparing dates contained in a data set to fixed dates written in the formula; however, I am unable to locate information related to comparing dates contained in a data set to an array of other dates contained in a data set.
Example scenario:
Suppose I send technicians to complete services at multiple times throughout the day, and many of these service calls overlap. At the time that a new service call is received, I already have multiple technicians out at other calls. I'd like to account for the number of technicians unavailable at the time a service call is received due to already being engaged in another call.
Here is an example data set format (direct image embedding not available for me yet:
Screenshot of Example Data File in Excel
):
Column A = Unique Order Numbers
Column B = Date and Time Service Requested
Column C = Date and Time Service Completed
Column D = Number of Technicians Responding
Column E = (calculated) Number of Technicians Unavailable
Focused question:
How do I sum the values in Column D, for which the date and time appearing in cell B2 is < any of the dates and times appearing in array C3:C9? (This is an OR problem). And then the calculations will need to be continued with each subsequent date and time appearing in Column B (e.g., sum the values in Column D, for which the date and time appearing in cell B3 is < any of the dates and times appearing in array C4:C9).
Assume I have sorted my data by the date and time appearing in Column B, most recent first.
In the example I have provided, order number 000008 was received on 09/30/2010 at 11:47:14 PM, but 9 technicians were still out engaged in other calls that were not completed by the time this new service call was received (yellow highlighted entries). How do I get Excel to calculate the value 9 (cell E2 that I have currently manually summed)?
Thank you for your guidance.
In cell E2, try this:
=SUMIF(C2:$C$9, ">"&B2, D2:$D$9)
Assuming that you order by the order number (which is numeric and will be in order of request time) this formula should do the trick:
=SUMIFS(D:D,C:C,">" & B2,A:A,"<" & A2)
This works by:
= SUMIFS( D:D, /*Sum the Number of techs currently repsonding*/
C:C, ">" & B2, /* WHERE the completion date/time is less than the Request time for the current order */
A:A,"<" & A2) /* AND the order number is less than the current order number --Could alternatively use column B:B as the range and B2 as the critera */
Edit:
Also need to count the datetime of the above records if the completion date is null.
=SUMIFS(D:D,C:C,">" & B2,A:A,"<" & A2) + SUMIFS(D:D,C:C,"",A:A,"<" & A2)
Am new to Google Docs, but have to create a cumulative report of comments that are flagged as positive or negative. I have 6 worksheets that ideally would populate to a single report, but I could create 6 individual reports for now.
In the source sheet, ColA is a numeric code identifying the category. Col B is the category description; Col C are the notes from one person; Col D is the code to identify it as positive or negative; Cols E and F are the notes from a 2nd person; G/H from a 3rd, etc.
The report sheet needs to transpose the vertical comments by category with the positive comments for all persons for the first category in Col G, the negative comments for the 1st category in Col H, etc for all 6 categories.
I was able to manually create this report using the following formula to extract the Positive comments from column C:
QUERY(EntrySheet1!C5:D15;"select * where D='P'")
But, it's pretty tedious to copy the formula laterally and vertically to accommodate all 6 categories and all 6 note takers.
So, my questions are whether or not there is an easier way to extract the information the way I need to report it. Also, is there a way to use something like Excel's Indirect function where I could use the concatenate function to build the formulas and the Indirect to evaluate that function. My thought here is that I could have an entry cell where I would identify which cumulative report I wanted to view by simply updating the cell. An alternative would be to load the data into an array and use a script to populate a static cumulative report. Real-time updating with formulas would be ideal, but creating a static report that is created from a script is acceptable. My biggest concern is the manual effort to update the formulas since they are sheet specific.
Use Google Spreadsheet INDIRECT function.
See the Google spreadsheets function list:
INDIRECT(reference)
Returns the reference specified by a text string. This function can also be used to
return the area of a corresponding string. Reference is a reference to a cell or an
area (in text form) for which to return the contents.
You might be able to feed the results of indirect into your query.