I want to create a new table from the existing data:
date | store | cost |
---|---|---|
2022-01-10 | a | 3000 |
2022-01-10 | b | 2500 |
And finally the targettable should look like:
date | store | cost |
---|---|---|
2022-01-10 | a | 96,77 |
2022-02-10 | a | 96,77 |
2022-03-10 | a | 96,77 |
2022-04-10 | a | 96,77 |
.... to last day of the month | a | 96,77 |
2022-01-10 | b | 80,65 |
2022-02-10 | b | 80,65 |
2022-03-10 | b | 80,65 |
... | b | 80,65 |
The query should insert into another bigquery table with new rows for each day of the month (like the 2nd table). The cost should devided by the day of the month to split the cost.
I tried a few querys, but cant find a solution: :(
Thank you!
Using this answer here I have calculated the number of days for each month, and then I have divided the monthly costs by it to get daily_avg_monthly_cost
. Then I Joined with an array generated table containing all the dates in each month of the year and got the final output.
Please note: a limitation of this solution is that the value "2022" is hardcoded.
WITH source_data as (
SELECT date('2022-01-10') as _month, 'a' as store, 3000 as cost
UNION ALL
SELECT date('2022-01-10') as _month, 'b' as store, 2500 as cost
UNION ALL
SELECT date('2022-02-10') as _month, 'a' as store, 4000 as cost
UNION ALL
SELECT date('2022-02-10') as _month, 'b' as store, 3500 as cost
), cost_table AS (
SELECT
FORMAT_DATE('%Y-%m', _month) AS month,
store,
cost/EXTRACT(DAY FROM (DATE_SUB(DATE_TRUNC(DATE_ADD(_month, INTERVAL 1 MONTH), MONTH),INTERVAL 1 DAY))) daily_avg_monthly_cost
FROM source_data
),days AS (
SELECT
d,
FORMAT_DATE('%Y-%m',d) AS month
FROM (
SELECT
*
FROM
UNNEST(GENERATE_DATE_ARRAY('2022-01-01', '2022-12-31', INTERVAL 1 DAY)) AS d
)
)
SELECT
days.d as date,
cost_table.store,
cost_table.daily_avg_monthly_cost
FROM cost_table
JOIN days ON CAST(cost_table.month AS STRING) = days.month
You might consider below as well.
WITH sample_table AS (
SELECT '2022-01-10' date, 'a' store, 3000 cost UNION ALL
SELECT '2022-01-10' date, 'b' store, 2500 cost
)
SELECT store, date, ROUND(cost / COUNT(1) OVER (PARTITION BY store, _date), 2) cost
FROM (
SELECT store, cost,
-- parse *date* STRING to DATE type
PARSE_DATE('%Y-%d-%m', date) AS _date,
FROM sample_table
), UNNEST(GENERATE_DATE_ARRAY(DATE_TRUNC(_date, MONTH), LAST_DAY(_date))) date;
Query results
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.