Oracle SQL需求:将3表关联结果无重叠拆分为两个列表
解决符合资格用户列表无重叠拆分的SQL方案
嘿,我来帮你搞定这个用户列表拆分的问题!首先明确下我们的目标:把**Table 1(符合项目资格的用户列表)**拆成两个完全不重叠的子集,列表1已经有可行查询了,现在重点是写出无重叠的列表2查询。
问题回顾
列表2需要包含Table 1中满足以下任一条件的所有用户及全部记录:
- 在Table 2中当日对应字段值为NULL
- 在Table 2中当日对应字段值不在6-23范围内
- 未出现在Table 2中
之前的查询因为条件重叠导致总记录数超了,下面给你两个靠谱的解决方案:
方案一:基于列表1的反向逻辑(最稳妥,避免重叠)
既然列表1的条件是「在Table 2中当日对应联系时间在6-23之间」,那列表2就是Table 1里完全不满足列表1条件的记录。用NOT EXISTS来关联列表1的核心逻辑,这样天然不会有重叠:
SELECT a.* -- 可以根据需求替换成你需要输出的字段,比如关联Table3、Table2的字段 FROM $A$ a JOIN $C$ c ON a.CUSTOMER_ID_ = c.CUSTOMER_ID_ LEFT JOIN $B$ b ON c.USER_ID = b.USER_ID WHERE NOT EXISTS ( -- 直接复用列表1的核心判断逻辑 SELECT 1 FROM $B$ b_inner WHERE c.USER_ID = b_inner.USER_ID AND ( TO_CHAR(sysdate, 'D') = 1 AND (b_inner.sunday >= 6 AND b_inner.sunday <= 23) OR TO_CHAR(sysdate, 'D') = 2 AND (b_inner.monday >= 6 AND b_inner.monday <= 23) OR TO_CHAR(sysdate, 'D') = 3 AND (b_inner.tuesday >= 6 AND b_inner.tuesday <= 23) OR TO_CHAR(sysdate, 'D') = 4 AND (b_inner.wednesday >= 6 AND b_inner.wednesday <= 23) OR TO_CHAR(sysdate, 'D') = 5 AND (b_inner.thursday >= 6 AND b_inner.thursday <= 23) OR TO_CHAR(sysdate, 'D') = 6 AND (b_inner.friday >= 6 AND b_inner.friday <= 23) OR TO_CHAR(sysdate, 'D') = 7 AND (b_inner.saturday >= 6 AND b_inner.saturday <= 23) ) )
方案二:直接匹配列表2的三个条件(逻辑清晰)
如果不想复用列表1的查询,也可以直接针对三个条件写严谨的过滤逻辑,用CASE表达式统一处理当日对应的字段,避免条件重叠:
SELECT a.* -- 按需选择要输出的字段 FROM $A$ a JOIN $C$ c ON a.CUSTOMER_ID_ = c.CUSTOMER_ID_ LEFT JOIN $B$ b ON c.USER_ID = b.USER_ID WHERE -- 条件3:用户未出现在Table2中 b.USER_ID IS NULL OR ( -- 条件1:当日对应字段为NULL;条件2:当日对应字段不在6-23范围内 CASE TO_CHAR(sysdate, 'D') WHEN '1' THEN b.sunday WHEN '2' THEN b.monday WHEN '3' THEN b.tuesday WHEN '4' THEN b.wednesday WHEN '5' THEN b.thursday WHEN '6' THEN b.friday WHEN '7' THEN b.saturday END IS NULL OR CASE TO_CHAR(sysdate, 'D') WHEN '1' THEN b.sunday WHEN '2' THEN b.monday WHEN '3' THEN b.tuesday WHEN '4' THEN b.wednesday WHEN '5' THEN b.thursday WHEN '6' THEN b.friday WHEN '7' THEN b.saturday END NOT BETWEEN 6 AND 23 )
为什么之前会出现重叠?
之前的查询大概率是把三个条件分开查询再用UNION ALL合并,但条件1和条件2是针对已在Table2的用户,条件3是不在Table2的用户,重复关联或者合并时没去重就会导致记录重复。上面的两种方法都是一次关联完成过滤,从根源上避免了重叠问题。
内容的提问来源于stack exchange,提问作者XD4
相关产品推荐
相关产品推荐

