使用Decode或NVL实现SQL查询去重,仅返回含'AU','RE','RW'的单条记录
问题解答
核心疑问回复
- 无法直接使用DECODE或NVL函数实现按用户去重的需求:DECODE是Oracle生态下的分支条件判断函数,NVL是空值替换函数,二者都属于单行处理函数,仅能对单条记录的单个字段值做转换,不具备按用户维度聚合、去重的能力,无法直接满足你每个用户仅返回1条记录的要求。
现有查询语句的问题
你当前的语句去重逻辑存在两处明显缺陷:
- 子查询逻辑错误:你写的
sfrstcr_reg_seq最大值查询的过滤条件写错了,where r2.sfrstcr_reg_seq = r1.sfrstcr_reg_seq等于没有按用户维度过滤,拿到的不是当前用户的最大reg_seq,完全起不到过滤作用,正确写法应该是where r2.sfrstcr_pidm = r1.sfrstcr_pidm distinct是对所有查询字段的组合去重,如果同一个用户存在多条不同r1.sfrstcr_rsts_code状态的符合条件记录,还是会返回同一个用户的多条数据,不符合你每个用户仅展示1条的要求。
优化方案(按用户唯一返回记录)
推荐用窗口函数ROW_NUMBER()实现,逻辑清晰性能也更好,Oracle、PostgreSQL、MySQL8.0+版本都支持:
select sfrstcr_rsts_code, spriden_last_name, spriden_first_name, saradap_appl_date, saradap_appl_no from ( select r1.sfrstcr_rsts_code, spriden_last_name, spriden_first_name, s1.saradap_appl_date, s1.saradap_appl_no, -- 按用户pidm分组,按申请号、注册序列倒序排序,每个用户只取第一条 row_number() over(partition by spriden_pidm order by s1.saradap_appl_no desc, r1.sfrstcr_reg_seq desc) rn from saradap s1 join spriden on spriden_pidm = s1.saradap_pidm left join sfrstcr r1 on s1.saradap_pidm = r1.sfrstcr_pidm and s1.saradap_term_code_entry = r1.sfrstcr_term_code where r1.sfrstcr_rsts_code in ('AU','RE', 'RW') and s1.saradap_term_code_entry = 202210 ) t where rn = 1 order by spriden_last_name
如果你的数据库不支持窗口函数,也可以用分组取最大值的方式实现,不需要额外加distinct关键字。
内容的提问来源于stack exchange,提问作者Tanque
相关产品推荐
相关产品推荐

