I'm writing a query in SQL to get the First, Last and Second last Transaction date for Customers. I have added the first and last using the Min() and Max() functions, how can I add the second last date in my query?
select distinct Shoppers, Min(Date) as First_Txn, Max(Date) as Last_Txn,
sum(revenue_sale) as Revenue, sum(units) as Units, count(distinct invoice) as Invoices,
from myTable
where Date between 20220101 and 20220131
group by 1;
I currently have a window function that takes all my data and finds the latest value (amount) for each account and then averages this across all accounts.
Now I want to segment by month. The problem is if there has been no data for the account in the month specified we need to get the last possible value used. Therefore we need each month to segment from the beginning of the month to the chosen month. Currently the query provides one value 'average amount'. Ideally I would like this average value for each month from inception
SELECT AVG(amount) as "average amount"
FROM (
SELECT *
FROM(
SELECT account_no,amount,_date,row_number() over(partition by account_no order by _date desc) as rn, source
FROM ('another subquery too long to write out fully') k
) j
WHERE j.rn = 1
) l
I have a google bigquery table with orders with a DATE column and other columns related to the orders. The starting date of the dataset is from 2021-01-01 (yyyy-mm-dd).
My aim is to filter on the DATE column from last year and this year to the previous iso week. For this, I used the ISOWEEK to create a new column:
WITH
last_week_last_year AS (
SELECT
DATE,
EXTRACT(ISOWEEK FROM DATE) AS isoweek,
FROM
`orders`
WHERE
EXTRACT(ISOWEEK FROM DATE) = EXTRACT(ISOWEEK FROM CURRENT_DATE())-1
GROUP BY 1, 2
ORDER BY DATE
)
SELECT * FROM last_week_last_year
This query results as the following table:
The issue is that when I filter on the original orders table by the DATE from the last_week_last_year table I get all the orders back instead of just the filtered version.
My method to filter is WHERE DATE IN (SELECT DATE FROM last_week_last_year) as seen below.
SELECT
*
FROM
`orders`
WHERE
DATE IN (SELECT DATE FROM last_week_last_year)
ORDER BY DATE DESC;
A snapshot of resulting table. It contains all of the records from 2021-01-01 until the latest day.
How can I make sure that on the latter query the table is filtered based on the first query's dates in DATE column?
I have a table that looks like this and I want to be able to summarize by ReportID the following. There should be one listing for a ReportID and type and the number of days in each month under the listed months. I don't want to have to figure out the begin and end date for the dataset, it should be automatic.
[
.
[
If you are working with Sql server and you need to calculate number of days between Startdate and EndDate within ReportId than you use window function sum and datetime function datediff (to count days):
select Type,ReportID,sum(datediff(dd,StartDate,EndDate))
over (partition by ReportId order by StartDate rows unbounded preceding)count_days_rep
from Table
Or if you need to summarize count days within ReportId and Type:
select Type,ReportID,sum(datediff(dd,StartDate,EndDate))
over (partition by ReportId,Type order by StartDate rows unbounded preceding) count_days_rep_type
from Table
EDIT:
At first, we counting days for startdate and enddate and then using Cross apply to get day's count in one column.
After that just summing values for each ReportId,Type:
(write comments):
--counting days for each month group by ReportId,Type
select ReportId,Type,Tab.month_num,
sum(Tab.count_days)count_days
from
(
select *,
--startdate: if startdate's month=enddate's month then difference between days
--ELSE count report days for startdate (counting days from this date to the end of the month)
case when datepart(month,StartDate)=datepart(month,EndDate) then datediff(dd,StartDate,EndDate)+1
else datepart(dd,EOMONTH(StartDate))-datepart(dd,StartDate)+1 end CountStartDays,
--stardate's month
datename(month,StartDate)MonthStartDate,
--enddate: if startdate's month=enddate's month then 0 (because this value taken into account already in CountStartDays) ELSE count report days for enddate
--(counting days from the begginning of enddate's month till date)
case when datepart(month,StartDate)=datepart(month,EndDate) then 0 else datepart(dd,EndDate) end CountEndDays,
--enddate's month
datename(month,EndDate)MonthEndDate
from Table
)y
CROSS APPLY
(values (MonthStartDate,CountStartDays),
(MonthEndDate, CountEndDays) ) Tab (month_num,count_days)
group by Type,ReportId,Tab.month_num
I hope you can appreciate my efforts.
I have data at the Cust_ID and Week_Date level with sales_dollars. Each Week_Date represents the sales_dollars for that week. I want to sum the dollars for each Cust_ID for the next 8 weeks. I want the final data at the Cust_ID and Week_Date level. Is that possible using sql?
You seem to want a window functions:
select t.*,
sum(sales) over (partition by cust_id
order by week_date
rows between current row and 7 following
) as sales_8weeks
from t;
This assumes that all weeks have data. If you want to put a range in by date, you can do that but the exact syntax varies by database.