现有订单操作记录表 t_order_log
,包含用户 ID,订单 ID,操作状态,操作时间。该表中操作状态包含下单、取消、改单,三种状态,用户取消订单后,则该订单不能再做修改。
有效订单:指未取消/改单的订单。
查询出用户最新的有效订单记录。
样例数据
+------------+------------+--------+---------------------+ | user_id | order_id | status | create_time | +------------+------------+--------+---------------------+ | U001 | ord001 | 1 | 2025-06-01 12:01:00 | | U001 | ord001 | 3 | 2025-06-01 12:02:00 | | U001 | ord001 | 2 | 2025-06-01 12:03:00 | | U001 | ord002 | 1 | 2025-06-01 12:05:00 | | U001 | ord003 | 1 | 2025-06-01 12:15:00 | | U001 | ord003 | 2 | 2025-06-01 12:20:00 | | U002 | ord004 | 1 | 2025-06-01 15:01:00 | | U002 | ord004 | 2 | 2025-06-01 15:02:00 | | U003 | ord005 | 1 | 2025-06-01 20:01:00 | | U003 | ord006 | 1 | 2025-06-01 20:02:00 | +------------+------------+--------+---------------------+
数据说明
- 用户 U001 的订单 ord001,ord003 最新状态均为取消单,有效单为 ord002
- 用户 U002 仅有一个订单 ord004,且最新状态为取消
- 用户 U003 有两个订单 ord005,ord006 且两单均有效,应取最新单 ord006
期望结果
+------------+------------+--------+---------------------+ | user_id | order_id | status | create_time | +------------+------------+--------+---------------------+ | U001 | ord002 | 1 | 2025-06-01 12:05:00 | | U003 | ord006 | 1 | 2025-06-01 20:02:00 | +------------+------------+--------+---------------------+
分析
根据订单的状态及操作时间来判断是否为最新的有效订单。
SQL
获取状态为 "下单" 的记录
获取每个用户、每笔订单,状态为 "下单" 的记录。
- 执行 SQL
select * from t_order_log where status = '1';
获取订单最后 "操作时间"
根据用户ID、订单ID分组后,获取订单最后 "操作时间"。
- 执行 SQL
select user_id, order_id, max(create_time) as max_create_time from t_order_log group by user_id, order_id;
判断有效订单的 "操作时间"
若有效订单的 "操作时间" 与订单最后 "操作时间" 相等,则表示该订单为 "最新有效订单"。
with a as ( select * from t_order_log where status = '1' ) ,b as ( select user_id, order_id, max(create_time) as max_create_time from t_order_log group by user_id, order_id ) select a.* from a inner join b on a.user_id = b.user_id and a.order_id = b.order_id and a.create_time = b.max_create_time;
+------------+------------+--------+---------------------+ | user_id | order_id | status | create_time | +------------+------------+--------+---------------------+ | U001 | ord002 | 1 | 2025-06-01 12:05:00 | | U003 | ord005 | 1 | 2025-06-01 20:01:00 | | U003 | ord006 | 1 | 2025-06-01 20:02:00 | +------------+------------+--------+---------------------+
从上述结果可知,用户 U003 存在两笔订单,不符合题目要求,还需要进一步处理。
完整脚本
with a as ( select * from t_order_log where status = '1' ) ,b as ( select user_id, order_id, max(create_time) as max_create_time from t_order_log group by user_id, order_id ) ,c as ( select a.* ,row_number() over(partition by a.user_id order by a.create_time desc) rn from a inner join b on a.user_id = b.user_id and a.order_id = b.order_id and a.create_time = b.max_create_time ) select * from c where rn = 1;
+------------+------------+--------+---------------------+ | user_id | order_id | status | create_time | +------------+------------+--------+---------------------+ | U001 | ord002 | 1 | 2025-06-01 12:05:00 | | U003 | ord006 | 1 | 2025-06-01 20:02:00 | +------------+------------+--------+---------------------+
建表语句
-- drop table student_score; create table if not exists student_score ( student string, subject string, score bigint ) comment '学生成绩表';
示例数据
-- drop table t_order_log; create table if not exists t_order_log ( user_id string comment '用户ID', order_id string comment '订单ID', status bigint comment '操作类型 1:下单;2:取消;3:改单', create_time string comment '操作时间' ); -- 样例数据 insert into t_order_log (user_id, order_id, status, create_time) values ('U001', 'ord001', 1, '2025-06-01 12:01:00'), ('U001', 'ord001', 3, '2025-06-01 12:02:00'), ('U001', 'ord001', 2, '2025-06-01 12:03:00'), ('U001', 'ord002', 1, '2025-06-01 12:05:00'), ('U001', 'ord003', 1, '2025-06-01 12:15:00'), ('U001', 'ord003', 2, '2025-06-01 12:20:00'), ('U002', 'ord004', 1, '2025-06-01 15:01:00'), ('U002', 'ord004', 2, '2025-06-01 15:02:00'), ('U003', 'ord005', 1, '2025-06-01 20:01:00'), ('U003', 'ord006', 1, '2025-06-01 20:02:00');
参考资料
原创文章,转载请注明出处:http://www.opcoder.cn/article/99/