Oracle SQL中基于Acc_ID的产品匹配:替代逐行对比的IN方案
Oracle SQL 修改CF字段逻辑的解决方案
针对你需要修改CF字段逻辑的需求,这里提供两种高效的实现方式:
方法1:子查询预计算匹配状态
先通过子查询找出所有存在Product1与Product2匹配的Acc_ID和Product1组合,再关联回原查询判断CF值:
SELECT o.*, a.*, CASE WHEN match_exists.ACC_ID IS NOT NULL THEN 'TRUE' ELSE 'FALSE' END AS CF FROM Oppty o LEFT JOIN Acc a ON o.ACC_ID = a.ACC_ID LEFT JOIN ( -- 提取存在匹配的Acc_ID与Product1唯一组合 SELECT DISTINCT o_inner.ACC_ID, o_inner.Product1 FROM Oppty o_inner JOIN Acc a_inner ON o_inner.ACC_ID = a_inner.ACC_ID AND o_inner.Product1 = a_inner.Product2 ) match_exists ON o.ACC_ID = match_exists.ACC_ID AND o.Product1 = match_exists.Product1;
逻辑说明
- 子查询
match_exists筛选出所有满足Product1=Product2的Acc_ID和Product1的唯一配对 - 原查询通过
LEFT JOIN关联该子查询,只要当前行的Acc_ID和Product1在子查询中存在,CF就设为TRUE,否则为FALSE
方法2:窗口函数直接计算(更简洁)
利用窗口函数按Acc_ID和Product1分组,统计组内是否存在匹配的Product2:
SELECT o.*, a.*, CASE WHEN MAX(CASE WHEN o.Product1 = a.Product2 THEN 1 ELSE 0 END) OVER (PARTITION BY o.ACC_ID, o.Product1) = 1 THEN 'TRUE' ELSE 'FALSE' END AS CF FROM Oppty o LEFT JOIN Acc a ON o.ACC_ID = a.ACC_ID;
逻辑说明
- 内层
CASE将匹配行标记为1,不匹配标记为0 - 窗口函数
MAX(...) OVER (PARTITION BY o.ACC_ID, o.Product1)针对每个Acc_ID+Product1分组,取组内的最大值:若组内存在匹配行,最大值为1,否则为0 - 外层
CASE根据最大值判断CF的最终值
补充说明
如果需要Oracle原生的布尔类型而非字符串,只需将'TRUE'/'FALSE'替换为TRUE/FALSE即可。
内容的提问来源于stack exchange,提问作者Noobanalyst415
相关产品推荐
相关产品推荐

