从订单信息表(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