DB2环境下如何筛选无PLACE_ORDER记录的目标订单
没问题,我来帮你解决这个DB2的查询问题。你要找的是那些在ORDER_STATUS表中完全没有PLACE_ORDER(对应SERVICE_NAME='OC')条目的订单,之前的查询之所以不对,是因为它会返回所有非OC的行——但如果某个订单同时存在OC和其他条目,那些非OC的行也会被拉出来,这显然不是你要的结果。
下面给你几种在DB2中可行的解决方案:
方法1:使用NOT EXISTS子查询(最直观的写法)
这种方法会直接排除掉所有存在OC条目的订单,剩下的就是完全没有OC条目的目标订单:
SELECT DISTINCT os.ORDER_NUMBER FROM ORDER_STATUS os WHERE NOT EXISTS ( SELECT 1 FROM ORDER_STATUS os2 WHERE os2.ORDER_NUMBER = os.ORDER_NUMBER AND os2.SERVICE_NAME = 'OC' );
如果需要获取这些订单的所有行数据,去掉DISTINCT改成SELECT os.*即可,不过通常这类需求只需要唯一的订单号列表。
方法2:使用GROUP BY + HAVING统计筛选
通过分组统计每个订单的OC条目数量,筛选出数量为0的订单:
SELECT ORDER_NUMBER FROM ORDER_STATUS GROUP BY ORDER_NUMBER HAVING COUNT(CASE WHEN SERVICE_NAME = 'OC' THEN 1 END) = 0;
这里的CASE语句只会统计SERVICE_NAME为OC的行数,HAVING子句直接过滤出没有OC条目的订单组。
方法3:使用LEFT JOIN匹配空值
通过左连接自身的OC条目,找出匹配失败(即无OC条目)的订单:
SELECT DISTINCT os.ORDER_NUMBER FROM ORDER_STATUS os LEFT JOIN ORDER_STATUS os2 ON os.ORDER_NUMBER = os2.ORDER_NUMBER AND os2.SERVICE_NAME = 'OC' WHERE os2.ORDER_NUMBER IS NULL;
LEFT JOIN会保留左表所有行,当右表(OC条目)匹配不到时,对应字段会为NULL,以此筛选出目标订单。
这三种方法在DB2中都能正常运行,你可以根据表的数据量选择效率最优的写法,通常NOT EXISTS和GROUP BY的性能表现都不错。
内容的提问来源于stack exchange,提问作者Vijay Kumar Rajput
相关产品推荐
相关产品推荐

