MySQL按组运行总计,时间间隔

时间:2020-06-26 08:04:50

标签: mysql sql date pivot window-functions

我想要一张这样的客户订单表:

customer_id | order_date | amount
0           | 2020-03-01 | 10.00
0           | 2020-03-02 |  2.00
1           | 2020-03-02 |  5.00
1           | 2020-03-02 |  1.00
2           | 2020-03-08 |  2.00
1           | 2020-03-09 |  1.00
0           | 2020-03-10 |  1.00
0           | 2020-03-16 |  1.00

并创建一个表,该表按周计算累计运行总计,并从最早的日期(2020-03-01、2020-03-08等)开始,按7天细分周。像这样:

customer_id | week_0 | week_1 |  week_2
0           | 12.00  | 13.00  |  14.00 
1           |  6.00  | 7.00   |   7.00
2           |  0.00  | 2.00   |   2.00

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您可以使用聚合和窗口函数(这需要MySQL 8.0)。将几周放入几行比几列放入几列更容易,更可伸缩:

select
    customer_id,
    year_week(order_date) order_week,
    sum(sum(amount)) over(partition by customer_id order by year_week(order_date)) running_amount
from mytable
group by customer_id, year_week(order_date)
order by customer_id, year_week(order_date)

您也可以将其转到列中-但是您需要枚举星期:

select
    customer_id,
    max(case when order_week = 202001 then running_amount end) week_01,
    max(case when order_week = 202002 then running_amount end) week_02,
    max(case when order_week = 202003 then running_amount end) week_03,
    ...
from (
    select
        customer_id,
        year_week(order_date) order_week,
        sum(sum(amount)) over(partition by customer_id order by year_week(order_date)) running_amount
    from mytable
    group by customer_id, year_week(order_date)
) t
order by customer_id

答案 1 :(得分:1)

我认为您要进行条件汇总-计算完第一笔订单日期后:

select customer_id,
       sum(case when order_date >= min_order_date + interval 0 day and order_date < min_order_date + interval 7 day
                then amount else 0
           end) as week_0,
       sum(case when order_date >= min_order_date + interval 7 day and order_date < min_order_date + interval 14 day
                then amount else 0
           end) as week_1,
       sum(case when order_date >= min_order_date + interval 14 day and order_date < min_order_date + interval 21 day
                then amount else 0
           end) as week_2
from (select t.*, min(order_date) over () as min_order_date
      from t
     ) t
group by customer_id;