如何修改PLSQL查询:优先返回指定single_portfolio行,否则返回其他行
实现优先返回指定portfolio记录的PLSQL查询
你需要实现的逻辑是:
- 当存在符合原查询条件且
single_portfolio = 100000885的记录时,仅返回该条记录 - 当不存在该记录时,返回所有符合原查询条件的记录
方法一:使用UNION ALL + NOT EXISTS
这种方法逻辑直观,通过两个查询分支组合结果:
SELECT * FROM test WHERE test.fee = 30003 AND test.date_from <= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND test.date_until >= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND test.single_portfolio = 100000885 UNION ALL SELECT * FROM test WHERE test.fee = 30003 AND test.date_from <= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND test.date_until >= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND NOT EXISTS ( SELECT 1 FROM test WHERE test.fee = 30003 AND test.date_from <= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND test.date_until >= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND test.single_portfolio = 100000885 );
- 第一个分支:精准筛选出目标portfolio的符合条件记录
- 第二个分支:仅当目标portfolio不存在符合条件记录时,返回原条件的所有记录
- 注意:
UNION ALL不会去重,确保结果准确
方法二:使用窗口函数(更高效)
通过一次表扫描完成逻辑判断,适合数据量较大的场景:
SELECT t.* FROM ( SELECT test.*, -- 标记优先级:目标portfolio优先级为1,其他为2 CASE WHEN test.single_portfolio = 100000885 THEN 1 ELSE 2 END AS priority, -- 统计符合条件的目标portfolio记录数量 COUNT(CASE WHEN test.single_portfolio = 100000885 THEN 1 END) OVER () AS has_target_portfolio FROM test WHERE test.fee = 30003 AND test.date_from <= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) AND test.date_until >= TRUNC(to_date('08/03/2020','dd/mm/yyyy')) ) t WHERE -- 存在目标记录时,仅返回优先级为1的行;不存在时返回所有行 (t.has_target_portfolio > 0 AND t.priority = 1) OR t.has_target_portfolio = 0;
- 内层查询通过窗口函数
COUNT() OVER ()判断是否存在目标portfolio的记录 - 外层查询根据标记的优先级和存在状态筛选最终结果
- 相比方法一,减少了一次表扫描,性能更优
内容的提问来源于stack exchange,提问作者jayzee
相关产品推荐
相关产品推荐

