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

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

需要用到的表:

订单信息表:order_info

order_id (订单id) user_id (用户id) create_date (下单日期) total_amount (订单金额)
1 101 2021-09-30 29000.00
10 103 2020-10-02 28000.00

期望如下结果:

user_id <string> order_id <string> create_date <string>
101 2 2021-09-28
101 3 2021-09-29
101 4 2021-09-30
102 5 2021-10-01
102 6 2021-10-01
102 8 2021-10-02
103 9 2021-10-02
103 10 2021-10-02
103 12 2021-10-03
104 13 2021-10-03
104 14 2021-10-03
104 15 2021-10-03
105 17 2021-10-04
105 18 2021-10-04
105 19 2021-10-04
106 22 2021-10-05
106 23 2021-10-05
106 24 2021-10-05
107 25 2021-10-05
107 27 2021-10-06
107 28 2021-10-06
108 29 2021-10-06
108 31 2021-10-07
108 32 2021-10-07
109 33 2021-10-07
109 35 2021-10-08
109 36 2021-10-08
1010 37 2021-10-08
1010 38 2021-10-08
1010 39 2020-10-08

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

1.使用dense_rank排名密集排名,按照用户分区日期排序,日期相同则排名相同,取排名1,2,3的所有信息即为最近三日的所有下单信息
sql 复制代码
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排名之后再展开
sql 复制代码
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排名获取排名日期,同时关联原表获取所有下单信息。
sql 复制代码
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
相关推荐
山岚的运维笔记1 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
WHD3063 小时前
苏州数据库(SQL Oracle)文件损坏修复
hadoop·sql·sqlite·flume·memcached
麦聪聊数据7 小时前
为何通用堡垒机无法在数据库运维中实现精准风控?
数据库·sql·安全·低代码·架构
枷锁—sha9 小时前
【SRC】SQL注入快速判定与应对策略(一)
网络·数据库·sql·安全·网络安全·系统安全
怣5012 小时前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql
证榜样呀13 小时前
2026 中专大数据技术专业可考的证书有哪些,必看!
大数据·sql
Codefengfeng14 小时前
数据安全知识点速通
sql
逍遥德15 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
驾数者15 小时前
Flink SQL实时数仓实战:基于Flink SQL的完整项目案例
sql·flink·linq