Reputation: 47
I have a table that adds new rows each Friday with a Report_Date attached. I will provide a sample table below:
Report_Date Value Item
1/1/2019 5 green
1/1/2019 5 blue
1/1/2019 4 red
1/8/2019 5 green
1/8/2019 6 blue
1/8/2019 3 red
1/15/2019 6 green
1/15/2019 5 black
1/15/2019 4 blue
1/15/2019 5 white
My desired result is to have a dynamic query that produces the below, and will add a new column each week as the table expands.
1/1/2019 1/8/2019 1/15/2019
5 5 6
5 6 5
4 3 4
null null 5
So far, I've been trying to use a full outer join to get what I need but this script is inefficient and will need to be rewritten every week. Note I am using Bigquery for this.
SELECT a.value AS WK1, b.value AS WK2
FROM table_1 a
FULL OUTER JOIN table_1 b
ON a.Item = b.Item
WHERE a.Report_Date = '1/1/2019'
AND b.Report_Date = '1/8/2019'
Upvotes: 0
Views: 664
Reputation: 692
if data is always collected on the same day, you can do something like this
with
sample_data as (
select
*
from
unnest(
array[
struct(date'2019-01-01' as report_date, 5 as value, 'green' as item),
struct(date'2019-01-01' as report_date, 5 as value, 'blue' as item),
struct(date'2019-01-01' as report_date, 4 as value, 'red' as item),
struct(date'2019-01-08' as report_date, 5 as value, 'green' as item),
struct(date'2019-01-08' as report_date, 6 as value, 'blue' as item),
struct(date'2019-01-08' as report_date, 3 as value, 'red' as item),
struct(date'2019-01-15' as report_date, 6 as value, 'green' as item),
struct(date'2019-01-15' as report_date, 5 as value, 'black' as item),
struct(date'2019-01-15' as report_date, 4 as value, 'blue' as item),
struct(date'2019-01-15' as report_date, 5 as value, 'white' as item)
]
)
)
select
sd.item,
md.max_report_date,
sum(if( sd.report_date = md.max_report_date,
sd.value, null)) as last_week_value,
-- uncomment if need this periods
-- date_sub(md.max_report_date, interval 7 day) as prev_report_date,
sum(if( sd.report_date = date_sub(md.max_report_date, interval 7 day),
sd.value, null)) as prev_week_value,
-- date_sub(md.max_report_date, interval 7 * 2 day) as last_minus_2_report_date,
sum(if( sd.report_date = date_sub(md.max_report_date, interval 7 * 2 day),
sd.value, null)) as last_minus_2_week_value,
-- date_sub(md.max_report_date, interval 7 * 3 day) as last_minus_3_report_date,
sum(if( sd.report_date = date_sub(md.max_report_date, interval 7 * 3 day),
sd.value, null)) as last_minus_3_week_value
from
sample_data as sd
cross join (select
max(report_date) as max_report_date
from
sample_data) as md
group by
1, 2
Upvotes: 2