历史日期的滚动总和

Rolling sum for historical dates

我有一个 table 订单 看起来像这样:

order_id sales_amount order_time store_id
1412412 30 2022/03/28 456
1551211 5 2022/03/27 145

我有兴趣滚动计算过去 28 天内收到第一笔订单的商店的销售额。以下将给我最近一天的这个:

with first_order_dates AS (
select 
min(order_time) as first_order_time, 
store_id
from Orders
group by store_id
)

select 
dateadd(day,-1, cast(getdate() as date)) AS date, 
sum(sales_amount) AS new_revenue_last_28d
from Orders
left join first_order_dates
on first_order_dates.store_id = Orders.store_id
where first_order_time between dateadd(day,-29, cast(getdate() as date)) and dateadd(day,-1, cast(getdate() as date))
group by dateadd(day,-1, cast(getdate() as date))

导致:

Date new_revenue_last_28d
2022/04/06 5400

我想要的是返回并计算历史上的每个日子,即以

结束
Date new_revenue_last_28d
2022/04/06 5400
2022/04/05 5732
2022/04/04 4300

等等,所以我可以绘制图表。我有 运行 的想法 - 我怎么能只用我可用的信息来做到这一点?理想地使用 Snowflake

因此,如果您只想显示过去 28 天内首次销售的商店的销售额,并且对于“这 28 天,滚动 window 这些销售额的总和”

WITH data as (
    select * from values
    (100, '2022-04-07'::date, 10),
    (100, '2022-04-06'::date, 8),
    (100, '2022-04-05'::date, 11),
    (100, '2022-04-01'::date, 12),
    (101, '2022-04-02'::date, 110),
    (101, '2022-04-01'::date, 120)
    t(store_id, order_date, sales_amount)
), store_valid_orders as (
    select 
        store_id
        ,order_date
        ,sales_amount
    from data
    qualify min(order_date) over(partition by store_id) >= current_date() - 28
), those_28_days as (
    select current_date() - row_number()over(order by null) + 1 as date
    from table(generator(ROWCOUNT => 29))
), day_join_sales as (
    select 
        d.date
        ,s.store_id
        ,sum(s.sales_amount) as sales_amount
    from those_28_days as d
    left join store_valid_orders as s on d.date = s.order_date
    group by 1,2
)
select 
    date
    ,store_id
    ,sum(sales_amount) over(partition by store_id order by date rows between 28 preceding and current row ) as prior_28_days_sales
from day_join_sales
qualify store_id is not null;

给出:

DATE STORE_ID PRIOR_28_DAYS_SALES
2022-04-01 100 12
2022-04-05 100 23
2022-04-06 100 31
2022-04-07 100 41
2022-04-01 101 120
2022-04-02 101 230

这实际上比它需要的更复杂..但我有一半的概念可以解决滚动 windows 天的问题,其中包括与滚动日期相关的首次销售。哪个更复杂,但以上内容可能足以回答您的问题。所以我就到此为止了。

拍摄 2:

每家商店每天 28 天的销售额,汇总为单日总计:

WITH data as (
    select * from values
    (100, '2022-04-07'::date, 10),
    (100, '2022-04-06'::date, 8),
    (100, '2022-04-05'::date, 11),
    (100, '2022-04-01'::date, 12),
    (101, '2022-04-02'::date, 110),
    (101, '2022-04-01'::date, 120)
    t(store_id, order_date, sales_amount)
), store_first_orders as (
    select 
        store_id
        ,min(order_date) as first_order
    from data
    group by 1
), _29_rows as (
    select
        row_number()over(order by null) - 1 as rn
    from table(generator(ROWCOUNT => 29))
), those_29_rows as (
    select
        v.store_id
        ,dateadd(day, r.rn, v.first_order) as date
    from _29_rows as r
    full join store_first_orders as v
), first_28_days_of_data as (
    select 
        r.store_id
        ,r.date
        ,d.sales_amount
    from those_29_rows r
    left join data as d
        on d.store_id = r.store_id AND d.order_date = r.date
), per_site_dailies as (
    select 
        store_id
        ,date
        ,sum(sales_amount) over(partition by store_id order by date) as roll_sales
    from first_28_days_of_data
    order by 2,1
)
select 
    date,
    sum(roll_sales) as new_revenue_last_28d
from per_site_dailies
group by 1
having date <= current_date()
order by 1;

给出:

DATE NEW_REVENUE_LAST_28D
2022-04-01 132
2022-04-02 242
2022-04-03 242
2022-04-04 242
2022-04-05 253
2022-04-06 261
2022-04-07 271
2022-04-08 271