I want to group the active customers per month based on the following condition included in the case statement below, ie bins per month.
I managed to get my results through a long case statement and UNION ALL but I believe there must be a smarter way to make this work with the help of a script and a loop through a dates reference table
Manual iteration query that worked:
SELECT customer_id WHEN ((DATE (start_time) >= '2022-03-01'
AND DATE(end_time) <= '2022-03-31')
OR (DATE(start_time) < '2022-03-01'
AND DATE_TRUNC(end_time,MONTH) = '2022-03-01')
OR (DATE(end_time)>'2022-03-31'
AND DATE_TRUNC(start_time,MONTH) ='2022-03-01')) THEN '2022-03-01' ELSE 'n.a' END AS MONTH ,
FROM customers
UNION ALL
SELECT customer_id CASE
WHEN ((DATE (start_time) >= '2022-04-01'
AND DATE(end_time) <= '2022-04-30')
OR (DATE(start_time) < '2022-04-01'
AND DATE_TRUNC(end_time,MONTH) = '2022-04-01')
OR (DATE(end_time)>'2022-04-30'
AND DATE_TRUNC(start_time,MONTH) ='2022-04-01')) THEN '2022-04-01'
ELSE 'n.a'
END AS MONTH ,
FROM customers
...........
SELECT customer_id CASE
WHEN ((DATE (start_time) >= '2022-12-01'
AND DATE(end_time) <= '2022-12-31')
OR (DATE(start_time) < '2022-12-01'
AND DATE_TRUNC(end_time,MONTH) = '2022-12-01')
OR (DATE(end_time)>'2022-12-31'
AND DATE_TRUNC(start_time,MONTH) ='2022-12-01')) THEN '2022-12-01'
ELSE 'n.a'
END AS MONTH ,
FROM customers
TLDR I want to create a loop that iterates through the dates_reference table, a script that creates these individual tables for me and unions them all in a final table.
dates_reference table
| first_day | last_day |
|---|---|
| 2022-03-01 | 2022-03-31 |
| 2022-04-01 | 2022-04-30 |
| .... | .... |
| 2022-12-01 | 2022-12-31 |
customers table
| customer_id | start_date | end_date |
|---|---|---|
| aj2 | 2022-03-21 | 2022-03-31 |
| bed1 | 2022-04-11 | 2022-05-30 |
| .... | .... | |
| dul9 | 2022-12-11 | 2022-12-31 |
This would be my approach in code, but I do not know how to write it in BQ:
start_date= first_day (loop trough the dates reference date )
end_date = last_day (loop trough the dates reference date )
query =f"""
SELECT customer_id WHEN ((DATE (start_time) >= start_date
AND DATE(end_time) <= end_date)
OR (DATE(start_time) < start_date
AND DATE_TRUNC(end_time,MONTH) = start_date)
OR (DATE(end_time)>end_date
AND DATE_TRUNC(start_time,MONTH) =start_date)) THEN start_date ELSE 'n.a' END AS MONTH , """