SQL:组中最近30天的总和

时间:2016-10-27 23:21:10

标签: sql amazon-redshift

我有一张表格如下:

date, custid, sales
2015-01-01, 01, 100
2015-01-10, 01, 200
2015-02-05, 01, 300
2015-03-02, 01, 400
2015-03-03, 01, 500
2015-01-01, 02, 100
2015-01-10, 02, 200
2015-02-05, 02, 300
2015-03-02, 02, 400
2015-03-03, 02, 500
...

如何按日期和custid生成最近30天的销售总额。

所需的输出是:

date, custid, running_30_day_sales
2015-01-01, 01, 100
2015-01-10, 01, 300 --(100+200)
2015-02-05, 01, 500 --(200+300)
2015-03-02, 01, 700 --(300+400)
2015-03-03, 01, 1200 -- (300+400+500)
2015-01-01, 02, 100
2015-01-10, 02, 300 --(100+200)
2015-02-05, 02, 500 --(200+300)
2015-03-02, 02, 700 --(300+400)
2015-03-03, 02, 1200 -- (300+400+500)

3 个答案:

答案 0 :(得分:3)

这是使用self join执行此操作的一种方法。每个日期都与其datediff为> 0且< = 30的所有日期相结合。此后,它只是一个分组操作。

select a1.custid, a1.dt, a1.sales+sum(coalesce(a2.sales,0)) total
from atable a1
left join atable a2 on a1.custid=a2.custid 
and datediff(day,a2.dt,a1.dt)<=30 and datediff(day,a2.dt,a1.dt)>0
group by a1.custid,a1.dt,a1.sales
order by 1,2

Sample Demo in Postgres

要更好地理解它,请使用

查看自联接的查询结果
select a1.*,a2.*
from atable a1
left join atable a2 on a1.custid=a2.custid 
and datediff(day,a1.dt,a2.dt)<=30 and datediff(day,a1.dt,a2.dt)>0

答案 1 :(得分:0)

使用累积总和这是一个诀窍:

with t as (
      select custid, date, sales from atable
      union all
      select custid, date + interval '30 day', sales from atable
     )
select custid, date,
       sum(sum(sales)) over (partition by cust_id order by date rows between unbounded preceding and current row) as sales_30day
from t
group by custid, date;

答案 2 :(得分:0)

你也可以用窗口函数这样找

SELECT custid, dt::date,
            SUM(sales) OVER (partition by custid ORDER BY dt
                            RANGE BETWEEN '30 days' PRECEDING AND '2 days' Following) as  sum_of_sales
            MIN(sales) OVER (partition by custid ORDER BY dt::date
                            RANGE BETWEEN '30 days' PRECEDING AND CURRENT ROW) as  minimum,
            MAX(sales) OVER (partition by custid ORDER BY dt::date
                            RANGE BETWEEN '2 days' PRECEDING AND '2 days' Following) as  maximum
      FROM atable