使用NVL、GROUP BY、HAVING COUNT校验记录一致性的SQL问题排查
咱们来拆解下你遇到的问题,以及怎么修复它:
首先,原始查询的核心问题:
- 连接条件用
AND完全逻辑错误:cust_dtl.CUST_REF_ID = cust_merge.NEW_CUST_REF_ID AND cust_dtl.CUST_REF_ID = cust_merge.OLD_CUST_REF_ID意味着要找一个客户ID同时等于NEW和OLD值,除非某行的NEW和OLD完全相同,否则这条条件永远匹配不到任何数据,导致EXISTS子查询返回假,最终结果就是N。 - 你的查询是全局返回一个结果,而不是针对
CUST_MERGE的每一行单独校验,这和你需要逐行判断的需求不匹配。
正确的解决方案:针对每行返回Y/N
如果你需要对CUST_MERGE的每一行,分别判断两个客户ID的CTRY_ID是否一致,这里有两种简洁的实现方式:
方法1:关联子查询直接比较
这种方式最直观,针对每行的两个ID分别查询对应的国家,然后直接比较:
SELECT cm.NEW_CUST_REF_ID, cm.OLD_CUST_REF_ID, CASE -- 分别获取两个ID对应的CTRY_ID,相等则返回Y WHEN (SELECT ctry_id FROM CUST_DETAILS WHERE CUST_REF_ID = cm.NEW_CUST_REF_ID) = (SELECT ctry_id FROM CUST_DETAILS WHERE CUST_REF_ID = cm.OLD_CUST_REF_ID) THEN 'Y' ELSE 'N' END AS SAME_CTRY_ID FROM CUST_MERGE cm;
针对你的样例数据,这个查询会返回:
| NEW_CUST_REF_ID | OLD_CUST_REF_ID | SAME_CTRY_ID |
|---|---|---|
| B5000 | B6000 | Y |
| B5000 | A6000 | N |
方法2:JOIN后分组判断
通过JOIN把两个客户的信息拉取出来,然后分组统计不同国家的数量:
SELECT cm.NEW_CUST_REF_ID, cm.OLD_CUST_REF_ID, CASE -- 如果两个ID对应的国家唯一,说明一致 WHEN COUNT(DISTINCT cd.CTRY_ID) = 1 THEN 'Y' ELSE 'N' END AS SAME_CTRY_ID FROM CUST_MERGE cm LEFT JOIN CUST_DETAILS cd ON cd.CUST_REF_ID IN (cm.NEW_CUST_REF_ID, cm.OLD_CUST_REF_ID) GROUP BY cm.NEW_CUST_REF_ID, cm.OLD_CUST_REF_ID;
这个方法的好处是可以处理其中一个ID不存在于CUST_DETAILS的情况(此时COUNT(DISTINCT)会是1或0,都会返回N,符合校验逻辑)。
可选:全局判断所有合并行是否都一致
如果你确实需要一个全局结果(判断所有合并行的国家是否都一致),可以基于上面的逐行结果再做一次聚合:
SELECT CASE WHEN COUNT(*) = SUM(CASE WHEN SAME_CTRY_ID = 'Y' THEN 1 ELSE 0 END) THEN 'Y' ELSE 'N' END AS ALL_SAME_CTRY FROM ( -- 这里嵌入上面方法1或方法2的查询 SELECT cm.NEW_CUST_REF_ID, cm.OLD_CUST_REF_ID, CASE WHEN (SELECT ctry_id FROM CUST_DETAILS WHERE CUST_REF_ID = cm.NEW_CUST_REF_ID) = (SELECT ctry_id FROM CUST_DETAILS WHERE CUST_REF_ID = cm.OLD_CUST_REF_ID) THEN 'Y' ELSE 'N' END AS SAME_CTRY_ID FROM CUST_MERGE cm ) t;
针对你的样例数据,这个全局查询会返回N,因为存在一行不一致的情况。
内容的提问来源于stack exchange,提问作者user2102665
相关产品推荐
相关产品推荐

