sql题之使用dense_rank,row_number,collect_set,later view explode解决最近日期信息的问题

从订单信息表(order_info)中查询出每个用户的最近三个下单日期的所有订单

需要用到的表:

订单信息表:order_info

order_id (订单id)user_id (用户id)create_date (下单日期)total_amount (订单金额)
11012021-09-3029000.00
101032020-10-0228000.00

期望如下结果:

user_id
<string>
order_id
<string>
create_date
<string>
10122021-09-28
10132021-09-29
10142021-09-30
10252021-10-01
10262021-10-01
10282021-10-02
10392021-10-02
103102021-10-02
103122021-10-03
104132021-10-03
104142021-10-03
104152021-10-03
105172021-10-04
105182021-10-04
105192021-10-04
106222021-10-05
106232021-10-05
106242021-10-05
107252021-10-05
107272021-10-06
107282021-10-06
108292021-10-06
108312021-10-07
108322021-10-07
109332021-10-07
109352021-10-08
109362021-10-08
1010372021-10-08
1010382021-10-08
1010392020-10-08

---总结,本题有三种做法,

1.使用dense_rank排名密集排名,按照用户分区日期排序,日期相同则排名相同,取排名1,2,3的所有信息即为最近三日的所有下单信息
select user_id, order_id,create_date
from ( select user_id , order_id, create_date,
       dense_rank()over (partition by user_id order by create_date desc) rk
       from order_info
     ) t1
where rk <= 3
2.使用collect_set获取所有的订单集合,然后使用later view explode炸裂集合,非常巧妙的把同一天的下单日期按照日期使用row_number排名之后再展开

   

select
    user_id,
    create_date,
    order_id
from(
    select
        user_id,
        collect_set(order_id) orders,
        create_date,
        row_number() over (partition by user_id order by create_date desc) rn
    from order_info
    group by create_date, user_id
)t lateral view explode(orders) tmp as order_id 
where rn <= 3;
      在当前写法中,某大佬使用了group by 和 partition by 同时结合在一起使用的方法,首先是

用group by 进行分组,然后collect_set形成集合,同时在对用户分区日期排名取排名。 之后便是对集合展开,从而获取排名中所有的日期的订单信息。

3.使用row_number排名获取排名日期,同时关联原表获取所有下单信息。
select
  t2.user_id,
  order_id,
  t2.create_date
from
  (
    select
      user_id,
      create_date
    from
      (
        select
          user_id,
          create_date,
          row_number() over (
            partition by
              user_id
            order by
              create_date desc
          ) rn
        from
          order_info
        group by
          user_id,
          create_date
      ) t1
    where
      rn <= 3
  ) t2
  join order_info oi on t2.user_id = oi.user_id
  and t2.create_da

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值