如何查询所有子表均不含指定值的父表数据?SQL语句优化求助
正确SQL写法实现需求
我明白你的问题了——你需要找出那些在所有子表(history_payslip_data_hours和history_payslip_data_other)里都不存在指定code值的父表记录,而不是只要某一个子表没code就返回。你的原SQL用了UNION,相当于把两个独立的条件结果合并,自然会拿到不符合要求的数据。
正确的SQL语句
SELECT DISTINCT p.id, p.year, p.month FROM history_payslip_data p INNER JOIN history_payslip zg ON p.payslip_id = zg.id WHERE -- 基础筛选条件 p.employee_id IN (2) AND p.payslip_type = 'PL' AND zg.locked = TRUE -- 确保hours子表中无指定code AND NOT EXISTS ( SELECT 1 FROM history_payslip_data_hours pu2 WHERE p.id = pu2.payslip_id AND pu2.code IN ('code1', 'code2', 'code3') ) -- 确保other子表中无指定code AND NOT EXISTS ( SELECT 1 FROM history_payslip_data_other pd2 WHERE p.id = pd2.payslip_id AND pd2.code IN ('code1', 'code2', 'code3') ) ORDER BY p.year DESC, p.month DESC;
逻辑说明
- 基础筛选:先通过
INNER JOIN关联history_payslip,确保只选中符合员工ID、薪资单类型、锁定状态要求的主表记录。 - 双NOT EXISTS校验:用两个
NOT EXISTS子查询分别检查两个子表——只有当两个子表都不存在匹配指定code的关联记录时,主表记录才会被纳入结果集,完全符合你“所有子表均不含指定code”的需求。 - 去重处理:
DISTINCT用来避免因表关联逻辑产生的重复记录,如果你的数据关联本身不会产生重复,也可以移除这个关键字。
原SQL的问题分析
你的原SQL用UNION合并了两个查询结果:第一个查询返回hours子表无指定code的记录,第二个返回other子表无指定code的记录。这会导致只要其中一个子表没code,哪怕另一个子表存在指定code的记录,也会被返回,和你需要的“所有子表都不含code”逻辑完全相反。
内容的提问来源于stack exchange,提问作者Sam_slo
相关产品推荐
相关产品推荐

