select first day of month in google sheets query - google-sheets

I am trying to construct a query that would among other columns return a date, which is in column J of an "rawData" table and change this date to the first day of month.
In my query all date statements but the last one are for testing purposes. The last one causes an error (Unknown range name: 'J'.). Anybody knows where is the mistake? This is my query:
=query(rawData;"select C, YEAR(J), MONTH(J)+1,
date'2010-08-31',
date '"&TEXT(2010-10-1;"yyyy-mm-dd")&"',
date '"&TEXT(CONCATENATE("2020-12";"-01");"yyyy-mm-dd")&"',
date '"&TEXT(CONCATENATE(YEAR(J);"-";MONTH(J);"-01");"yyyy-mm-dd")&"',
SUM(L)
WHERE (C<>'')
AND (F=18 OR F=20 OR F=62)
group by C, YEAR(J), MONTH(J)+1";1
)
Thanks,
Andrej

First, refer the documentation for the Query Language Reference, particular the use of [Scalar Functions] (https://developers.google.com/chart/interactive/docs/querylanguage#scalar-functions). The options here are very limited and do not appear to permit the calculation of the 'first of the month' within the query, per se.
It is possible to build the 'first of the month' within the rawData sheet, and I'll demonstrate the process, but I'll think you will agree that it doesn't achieve any perceivable advantage.
Try this.
Helper Column P
1) Create a helper column "P" in rawData. In cell P2, enter this formula:
=arrayformula(IF(ISBLANK(J2:J);"";DATE(Year(J2:J);Month(J2:J);1)))
Select the entire column and format it as Date 'yyyy-mm-dd'.
This is your "first of the month date". For identification, enter "Date yyyy-mm-dd" in Cell P1.
Query#1
2) Create a new sheet for testing. In cell A1 enter this formula:
=query(rawData!A2:P;"Select C, sum(L) WHERE (C<>'') AND (F=18 OR F=20 OR F=62) group by C label C 'Reg_st_vozila',sum(L) 'Total'").
This is the product code and sum by quantity, grouped by Product Code; you should have 24 records.
Query#2
3) In the same new sheet, in cell D1 enter this formula
=query(rawData!A2:P;"Select C, P, sum(L) WHERE (C<>'') AND (F=18 OR F=20 OR F=62) group by C,P label C 'Reg_st_vozila', P 'Date', sum(L) 'Total'")
This is the product code and sum by quantity, grouped by Product Code and First of the Month date (the date from the Helper Column). You should have 1142 records.
Query#3
4) In the same new sheet, in cell H1 enter this formula:
=query(rawData!A2:P;"Select C, Year(J), Month(J)+1, sum(L) WHERE (C<>'') AND (F=18 OR F=20 OR F=62) group by C,Year(J),Month(J)+1 label C 'Reg_st_vozila', Year(J) 'Year', Month(J)+1 'Month', sum(L) 'Total'")
This is the product code and sum by quantity, grouped by Product Code by Year by Month date. You should have 1142 records.
The output is identical to the preceding formula, though the query has an extra field (one for Year, one for Month). My point is that the 'first of month' doesn't achieve anything special.
Helper Column Q
5) Create a second helper column "Q" in rawData. In cell Q2, enter this formula:
=arrayformula(J2:J)
Select the entire column and format it as Date 'yyyy-mm'.
This is a modification of the date column, but formatted for year-month.
For identification, enter "Date yyyy-mm" in Cell Q1.
Query#4
6) In the new query sheet, in cell M1 enter this formula:
=query(rawData!A2:Q;"Select C, Q, sum(L) WHERE (C<>'') AND (F=18 OR F=20 OR F=62) group by C,Q label C 'Reg_st_vozila', Q'Year/Month', sum(L) 'Total'")
This is the product code and sum by quantity, grouped by Product Code by Year & Month. You should have 1142 records.
The output is identical to Query#2 but without the aggravation of calculating the "first of the month. Again, it shows that grouping on 'fom' doesn't achieve any perceivable advantage.

Related

Google sheets sumif with odd data

I have sales data that gives me dates in a bad format. Every new sale gets automatically added to the sheet. Looks like this:
Column A
Column B
Column C
Order 1
2022-12-02T02:09:37Z
$1025.19
Order 2
2022-12-02T01:25:15Z
$873.65
This will continue on for all sales. Now the date format is UTC for whatever reason and I can't adjust that, so within this formula I have to subtract 6 hours to get it to central time. I'm trying to create an auto-updating chart that shows an average day for 7 days, so I'm trying to do a sumif formula.
Here's what I have on Sheet2:
=sumif(Sheet1!C:C,index(split((index(split(Sheet1!B:B,"T"),1)+index(split(left(Sheet1!B:B,19),"T"),2))-0.25,"."),1),A1)
Where A1 is a single date. Testing this with one date and not the range shows that it does match. When I do the range, the total comes to 0, even though multiple different dates should match. What am I doing wrong?
Assume A1 has the value: 2022-12-02T02:09:37Z
Apply this formula:
=LAMBDA(RAW,TUNEHOUR,
LAMBDA(DATE,TIME,
TEXT((DATE&" "&TIME)+TUNEHOUR/24,"yyyy-mm-dd hh:mm:ss")
)(TEXT(INDEX(RAW,,1),"yyyy-mm-dd"),REGEXREPLACE(INDEX(RAW,,2),"Z",""))
)(SPLIT(A1,"T"),-6)
returns:
2022-12-01 20:09:37
And assume you have a set of data like this:
you can apply this formula:
=ArrayFormula(
LAMBDA(DATES,AMOUNTS,START,END,DFORMAT,TFORMAT,SKIPBLANK,TUNEHOUR,
LAMBDA(DATES,AMOUNTS,DTFORMAT,START,END,
LAMBDA(DATES,TIMES,
LAMBDA(VALIDDATES,AMOUNTS,
TEXT(SUM(FILTER(AMOUNTS,VALIDDATES>=START,VALIDDATES<=END)),"$#,##0.00")
)(TEXT((DATES&" "&TIMES)+TUNEHOUR/24,DTFORMAT),IF(ISNUMBER(AMOUNTS),AMOUNTS,VALUE(REGEXEXTRACT(AMOUNTS,"^\$(.+)"))))
)(TEXT(INDEX(DATES,,1),DFORMAT),REGEXREPLACE(INDEX(DATES,,2),"Z",""))
)(SPLIT(QUERY({DATES},SKIPBLANK),"T"),QUERY({AMOUNTS},SKIPBLANK),DFORMAT&" "&TFORMAT,TEXT(START,DFORMAT)&" 00:00:00",TEXT(END,DFORMAT)&" 23:59:59")
)($B$5:$B,$C$5:$C,$B$1,$B$2,"yyyy-mm-dd","hh:mm:ss","WHERE Col1 IS NOT NULL",-6)
)
Where you enter a start date and an end date at B1 & B2 to sum up the amount with.
The provided date column will be deducted by 6 hours.
What this formula does is...
format the date column into a valid date,
compare dates from step 1 with a given start and end date as filter condition,
filter the given amount column with conditions from step 2,
sum the result of filter from step 3 as an array,
format the output as price.
Use regexreplace() and query(), like this:
=arrayformula(
query(
{
weeknum(
regexreplace(B2:B, "([-\d]+)T(\d\d:\d\d).+", "$1 $2")
-
"6:00"
),
C2:C
},
"select Col1, avg(Col2)
where Col1 is not null
group by Col1
label Col1 'week #' ",
0
)
)
I think you're trying to split the values and sum them. I can't understand fully what's the purpose of 19 in LEFT function, and why are you again splitting it? Maybe some approach similar to yours is use LEFT function with 10 characters for the date, and MID from 12th character to get the time. Then substract .25 for the 6 hours as you did, and ROUNDDOWN with 0 digits to get the only the day
=ARRAYFORMULA(ROUNDDOWN(LEFT('Sheet1'!B:B,10)+MID('Sheet1'!B:B,12,8)-0.25,0))
And then you can insert it in your SUMIF:
=SUMIF(Sheet1!C:C,ARRAYFORMULA(ROUNDDOWN(LEFT(Sheet1!B:B,10)+MID(Sheet1!B:B,12,8)-0.25,0)),A1)

Formula to build report of employees that are not working between 2 dates

I am trying to find a way to see which employees are not working between 2 dates.
Should I use vlookup, index & match, filter, query, or something else?
Sheet 1 contains employee details & start/end dates.
Sheet 2 accepts user input to select 2 dates, and it will automatically display a list of available employees who are not working.
Sheet 1 - Database/Log of all employees and days worked.
#
A
B
C
D
1
ID
Name
Start Date
End Date
2
12345
John
01/01/2021
01/08/2021
3
54321
Sarah
01/24/2021
01/29/2021
4
00731
James
02/05/2021
02/15/2021
5
00731
John
02/10/2021
02/30/2021
Sheet 2 (Row 1-2)- Manually enter in two dates.
#
A
B
1
Start Date (Manual input)
End Date (Manual input)
2
01/01/2021
01/30/2021
Sheet 2 (Row 3+)- List of all employees that are not working between the two dates entered in Sheet 2!A2:B2 (Expected Results)
#
A
B
3
ID
Name
4
00731
James
try:
=INDEX(SUBSTITUTE(UNIQUE(QUERY(""&SPLIT(FLATTEN(IF(SEQUENCE(1, MAX(D2:D-C2:C))<=D2:D-C2:C,
"♥"&A2:A&"♦"&B2:B&"♦"&C2:C+SEQUENCE(1, MAX(D2:D-C2:C), 0), )), "♦"),
"select Col1,Col2 where not Col3 matches '"&JOIN("|", "^$",
IF(SEQUENCE(1, G2-F2)<=G2-F2, F2+SEQUENCE(1, G2-F2, 0), ))&"'", 0)), "♥", ))
demo sheet
Assuming the name of your first sheet with the full data is actually Sheet1, place the following in Sheet2 cell A4:
=FILTER(Sheet1!A2:B,Sheet1!A2:A<>"",(Sheet1!C2:C>G2)+(Sheet1!D2:D<F2))
The combined either/or condition (Sheet1!C2:C>G2)+(Sheet1!D2:D<F2) in the FILTER means "either the start date is after the range date given, or the end date is before the range date given."
The other condition of Sheet1!A2:A<>"" just rules out blank rows in the original data set. It's not strictly necessary as far as the visual results are concerned; but it keeps null rows from being added to those results, which would allow you to enter data below the results in Col A and B of Sheet2 if you wanted, or to have fewer rows in Sheet2 than in Sheet1 without the formula adding more rows to accommodate null returns.
Your posted sample data is unclear. You have two different names for the same ID (i.e., 00731). And you have an "End Date" in D5 of February 30, 2021—which is not a valid date. In any case, it's unclear whether the same person/ID may turn up twice in the original data set. My formula above assumes you will not.
If your original data list may, in fact, contain duplicates, things get a bit trickier. In that case, use the following formula instead, in Sheet2 cell A4:
=UNIQUE(FILTER(A2:B,ISERROR(VLOOKUP(A2:A,FILTER(A2:A,((C2:C>=F2)*(C2:C<=G2))+((D2:D>=F2)*(D2:D<=G2))),1,FALSE))))
Here, the inner FILTER first forms a list of all people who are working during that range, and then the outer FILTER filters in a UNIQUE set of the people who are not on that inner list (i.e., trying to VLOOKUP them returns IS(an)ERROR).

Google Sheets query function needing to provide 0 value for no value found

The query function looks at a separate sheet with orders entered by a dealer. In some months the dealer may not have a order. The B:B column in current sheet is all the dealers in Ascending order. Then I have separate columns for by month view with 3 columns per month. Number of contracts, amount then average. My query calculates correctly, but if a dealer doesn't have a contract then it skips. So my list is out of order. I'm needing it to place a 0 if no value found. I have 2 versions of the query.
J = amount, H = Dealer name, A = Date, the B = is the dealer list in current sheet.
This query populates but out of order due to skipping NUll or NA.
=QUERY('2021ContractsData'!A:V,
"Select COUNT(J),SUM(J),AVG(J)
WHERE MONTH(A)+1=1
Group By H LABEL COUNT(J) 'Contracts',SUM(J) 'Amount',AVG(J) 'Average'")
This query populates nothing, it shows the Header names but no values in rows.
=QUERY('2021ContractsData'!A:V,
"Select COUNT(J),SUM(J),AVG(J)
WHERE MONTH(A)+1=1
AND H='"&B2:B&"'
Group By H LABEL COUNT(J) 'Contracts',SUM(J) 'Amount',AVG(J) 'Average'")
Google Sheet View
try in C2:
={"Contracts", "Amount", "Average";
INDEX(IFNA(VLOOKUP(B3:B, QUERY('2021ContractsData'!A:V,
"select H,count(J),sum(J),avg(J)
where month(A)+1=1
group by H"), {2,3,4}, 0), 0))}

How to reduce Inventory in sheet1("stock") on the bases of product sold in sheet2("sales") through google sheets script...?

In Google Sheets for inventory management, sheet1 is stock in which Product and Quantity are mentioned, sheet2 is the sale of the day. I want to automatically deduct stock when a product is written over there, if apple is sold, then it should automatically deduct one quantity from sheet1.
The sheet is here.
Some code like this:
function onedit(sheet2,A2) {
if the product in Sheet2!A2 is in Sheet1!A2:A,Subtract 1 from Sheet1!B2:B
}
In your cell B2, you can insert this formula:
= 4 - SUM(QUERY(sold!$A$1:B,
"select count(A)
where A = '" & A2 & "'
group by A", false))
Then, you can drag it down to let the formula apply to all your rows.
The formula counts the number of occurrences in the "sold" sheet of the term in the column A of the first sheet. The QUERY function returns a table with one column and two rows (header and data). the SUM is applied to it, and reduces the QUERY result to a single number.
As with all formulas, results are kept up to date by the Google sheet automatically.
Instead of having the initial inventory in the formula itself, I suggest to use a separate column, for example column C. The formula above would then start with C2 instead of 4.

Counting recent visits based on date range

I have one column with Name.
I have a 2nd column with Date associated with a visit.
I wanted to generate a count of how many times the person has visited in a previous number of days.
If the number is greater than X, I want to fill another column with match.
I'm having trouble figuring out how to filter out names that don't match the row, while simultaneously counting how many times that person has dates that fall within the 7 day range.
So if John visited on 1/23, 2/4, 2/6, and 2/8, and the range is 7 days, it should add "3" to the "recent visits" column next to John's 2/8 row, fill 2 into the "recent visits" column for 2/6, and 1 for 2/4 and 1/23.
There will be other rows with other names that will have the same requirements, so it would also need to filter out names that don't match John.
What I'm trying to do with this, is trigger an alert through Zapier to send an email when there is a frequent visitor match.
cell C2: =UNIQUE(FILTER(A2:A, A2:A<>""))
cell D2:
=COUNTA(QUERY(ARRAYFORMULA($A$2:$B),
"select A where B >= date '"&TEXT(TODAY()-7, "yyyy-mm-dd")&"'
and B <= date '"&TEXT(TODAY(), "yyyy-mm-dd")&"'
and A = '"&C3&"'", 0))
and drag down from D2 cell

Resources