SQL 刷题 累计订单金额问题

需求描述

现有订单信息表如下:

create table t_simple_order
(
    uid    int,    --用户id
    day_id date,--订单日期
    ant    numeric --订单金额
);
insert into t_simple_order values (1,'2023-02-01'),(1,'2023-03-02'),(1,'2023-04-02');
insert into t_simple_order values (2,'2023-03-11'),(2,'2023-03-15'),(2,'2023-04-01');

要求计算每个用户首次订单日期后30天内累计订单金额,要求输出,用户ID,首次订单日期,30天内累计订单累计金额

解题思路

题目其实很简单,第一步找出每个用户首次下单时间,此处可以使用聚合函数min对下单时间求最小值,就是首次下单,然后对每个用户每天的下单金额进行汇总,然后进行关联即可

参考实现

select t.uid,
       t.fisrst_day,
       sum(sum_ant) filter ( where t1.day_id between t.fisrst_day and (t.fisrst_day + 30) ) total_ant
from (select uid, min(day_id) fisrst_day
      from t_simple_order
      group by uid) t
         left join
     (select uid, day_id, sum(ant) sum_ant
      from t_simple_order
      group by uid, day_id) t1 on t.uid = t1.uid
group by t.uid, t.fisrst_day;

此处使用了 post过热SQL 为聚合函数的一个扩展项 filter 实现,也可以使用 case when 对时间进行过滤

select t.uid,
       t.fisrst_day,
       sum(case when t1.day_id between t.fisrst_day and (t.fisrst_day + 30) then sum_ant end) total_ant
from (select uid, min(day_id) fisrst_day
      from t_simple_order
      group by uid) t
         left join
     (select uid, day_id, sum(ant) sum_ant
      from t_simple_order
      group by uid, day_id) t1 on t.uid = t1.uid
group by t.uid, t.fisrst_day;

最后给出本题的Hive解法

select t.uid,
       t.fisrst_day,
       sum(if(t1.day_id between t.fisrst_day and  date_add(t.fisrst_day,30), sum_ant, 0)) total_ant
from (select uid, min(day_id) fisrst_day
      from t_simple_order
      group by uid) t
         left join
     (select uid, day_id, sum(ant) sum_ant
      from t_simple_order
      group by uid, day_id) t1 on t.uid = t1.uid
group by t.uid, t.fisrst_day;
posted @ 2023-04-23 07:18  晓枫的春天  阅读(162)  评论(0编辑  收藏  举报