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
相关推荐
web2u1 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
yaoxin5211235 小时前
第三章 C 开头的术语
sql·iris
Yeats_Liao8 小时前
Navicat 导出表结构后运行查询失败ERROR 1064 (42000): You have an error in your SQL syntax;
数据库·sql
Zda天天爱打卡14 小时前
【趣学SQL】第二章:高级查询技巧 2.2 子查询的高级用法——SQL世界的“俄罗斯套娃“艺术
数据库·sql
苏-言15 小时前
MyBatis最佳实践:动态 SQL
数据库·sql·mybatis
Amd7941 天前
深入探讨存储过程的创建与应用:提高数据库管理效率的关键工具
sql·性能优化·数据安全·存储过程·数据库管理·业务逻辑·创建存储过程
MrZhangBaby1 天前
SQL-leetcode—1158. 市场分析 I
java·sql·leetcode
摘星怪sec1 天前
【漏洞复现】|方正畅享全媒体新闻采编系统reportCenter.do/screen.do存在SQL注入
数据库·sql·web安全·媒体·漏洞复现
十二同学啊1 天前
JSqlParser:Java SQL 解析利器
java·开发语言·sql
莫名有雪1 天前
BUUCTF_Web([RCTF2015]EasySQL)二次注入+报错注入
sql