如何不使用子查询实现按用户ID获取最新订单信息?
无嵌套子查询的SQL实现方案
针对你的需求,结合原SQL的Oracle环境(用到dual表和sysdate函数),提供两种无需子查询的实现方法:
方法一:使用Oracle专属的KEEP聚合子句
WITH test AS ( SELECT 1 AS user_id, 'sadasdasggg1' AS order_id, sysdate - 1 AS order_date FROM dual UNION SELECT 1, 'sadasdasggg2', sysdate - 2 FROM dual UNION SELECT 1, 'sadasdasggg3', sysdate - 3 FROM dual UNION SELECT 2, 'sadasdasggg4', sysdate - 4 FROM dual ) SELECT user_id, MAX(order_id) KEEP (DENSE_RANK LAST ORDER BY order_date) AS order_id, MAX(order_date) AS order_date FROM test GROUP BY user_id;
这个写法的逻辑是:先按order_date倒序筛选每个user_id下的最晚记录分组,再从该分组里取出order_id(如果同一个用户存在多条相同时间的最新订单,会取order_id最大的;若业务保证订单日期唯一,结果和原SQL完全一致)。
方法二:使用QUALIFY子句(Oracle 12c+及部分数据库支持)
如果你的Oracle版本是12c及以上,或者使用支持QUALIFY语法的数据库,可以直接用这个子句过滤窗口函数结果,无需嵌套:
WITH test AS ( SELECT 1 AS user_id, 'sadasdasggg1' AS order_id, sysdate - 1 AS order_date FROM dual UNION SELECT 1, 'sadasdasggg2', sysdate - 2 FROM dual UNION SELECT 1, 'sadasdasggg3', sysdate - 3 FROM dual UNION SELECT 2, 'sadasdasggg4', sysdate - 4 FROM dual ) SELECT user_id, order_id, order_date FROM test QUALIFY ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date DESC) = 1;
QUALIFY的作用和原SQL中子查询的WHERE rn=1完全一致,只是把过滤逻辑直接放在主查询后,省去了子查询嵌套。
内容的提问来源于stack exchange,提问作者nc1318
相关产品推荐
相关产品推荐

