I need to add another calendar to the current view table. The table already includes a column for month and year, but some months have no transactions, so they don't show up in the table. I want to create a new calendar field to display monthly sales, regardless of whether there are any transactions. How would I do this?
Sample script:
select T.MONTH_YEAR,
ROUND(SUM(T.GROSS_AMOUNT),3) AS CURRENT_GROSS_AMOUNT,
lag(ROUND(SUM(T.GROSS_AMOUNT),3)) over (partition by T.MATERIAL order by min(T.MONTH_YEAR)) as PREV_GROSS_AMOUNT
from transactions T
Here's the output:
MONTH_YEAR | CURRENT_GROSS_AMOUNT | PREV_GROSS_AMOUNT |
---|---|---|
Jan 2024 | 200 | |
Feb 2024 | 200 | 200 |
Mar 2024 | 300 | 200 |
Apr 2024 | 400 | 300 |
Jul 2024 | 500 | 400 |
Aug 2024 | 600 | 500 |
The final script should be something like this:
select T.MONTH_YEAR,
/*add another calendar to display 2 months no display */
ROUND(SUM(T.GROSS_AMOUNT),3) AS CURRENT_GROSS_AMOUNT,
lag(ROUND(SUM(T.GROSS_AMOUNT),3)) over (partition by T.MATERIAL order by min(T.MONTH_YEAR)) as PREV_GROSS_AMOUNT
from transactions T
Which would output:
MONTH_YEAR | calendar date | CURRENT_GROSS_AMOUNT | PREV_GROSS_AMOUNT |
---|---|---|---|
Jan 2024 | Jan 2024 | 200 | |
Feb 2024 | Feb 2024 | 200 | 200 |
Mar 2024 | Mar 2024 | 300 | 200 |
Apr 2024 | Apr 2024 | 400 | 300 |
May 2024 | 0 | 400 | |
Jun 2024 | 0 | 0 | |
Jul 2024 | Jul 2024 | 500 | 0 |
Aug 2024 | Aug 2024 | 600 | 500 |
All you need is :
FROM
UNNEST(GENERATE_DATE_ARRAY('2024-01-01', '2024-12-31', INTERVAL 1 MONTH)) AS month_date
Step 1: Create a calendar table [ you can change the date range as per your need]. This is the part which you basically need in your code the rest you can change as you wish.
Step 2: Aggregate transaction data by month (what you have done so far)
Step 3: Left Join the calendar with transaction data, this will join the data together and still show the calendar dates which are not being used for any transaction
WITH calendar AS (
SELECT
FORMAT_DATE('%b %Y', month_date) AS month_year,
month_date
FROM
UNNEST(GENERATE_DATE_ARRAY('2024-01-01', '2024-12-31', INTERVAL 1 MONTH)) AS month_date
),
transaction_data AS (
SELECT
FORMAT_DATE('%b %Y', PARSE_DATE('%b %Y', T.month_year)) AS month_year,
ROUND(SUM(T.gross_amount), 3) AS current_gross_amount
FROM
transactions T
GROUP BY
month_year
)
SELECT
c.month_year,
IFNULL(td.current_gross_amount, 0) AS current_gross_amount,
LAG(IFNULL(td.current_gross_amount, 0)) OVER (ORDER BY c.month_date) AS prev_gross_amount
FROM
calendar c
LEFT JOIN
transaction_data td
ON
c.month_year = td.month_year
ORDER BY
c.month_date