欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

sql一关联多查询时否定筛选出现的问题的解决

程序员文章站 2023-01-01 15:17:48
一方关联多方查询时执行否定筛选,结果包含未通过筛选的项。 我们规定一方为父,多方为子,我们希望子未通过筛选时,结果也不出现对应的父。 ......

问题:一方关联多方查询时执行否定筛选,结果包含未通过筛选的项。

我们规定一方为父,多方为子,我们希望子未通过筛选时,结果也不出现对应的父。

 

查询部门及部门下的所有员工。

select * from department left join employee on department.id = employee.did;

sql一关联多查询时否定筛选出现的问题的解决

查询不是员工tom所在的部门及部门下的所有员工。

第一想法是:select * from department left join employee on department.id = employee.did where employee.name != 'tom';

但是结果如下,结果仍包含部门 1 ,当mybatis等处理结果时,就会为部门 1 创建实例。这不是我们想要的。

sql一关联多查询时否定筛选出现的问题的解决

解决1:not in 的思想(这个很慢,直接看解决2)

not in 的思想是:先查出条件句的肯定,然后外部用not in筛选。

这里就是,先找出有员工tom的部门,然后筛选不是这个部门的所有部门及员工。

select *  from department left join employee on department.id = employee.did where department.id

not in (select department.id from department left join employee on department.id = employee.did where employee.name = 'tom');

not in 筛选id的时候使用最后一个一方的id,会更快一点。

例如:a  多对一  b  一对一  c  多对一  d  多对多  e

这个时候一直到 d 都是一方 所以 not in 时使用 d 的字段筛选。即...where d.column not in (select d.column from...

解决2:not in 的思想进阶

使用left join 代替 not in。

将not in 的子查询当做一个表,对其进行关联,然后筛选这个表字段为空的。

例如还是这个例子

select department.id from department left join employee on department.id = employee.did where employee.name = 'tom';

我们设这个表为 nodepartment 列为 id。结果应该只有一行一列 ‘1’。

则主表关联nodepartment后  department.id 为 2 的行 nodepartment.id这一列为null。所以主表条件 nodepartment.id is null就可以了。

在这里就是:

select *  from department left join employee on department.id = employee.did

left join 

 (select department.id as nodepid from department left join employee on department.id = employee.did

where employee.name = 'tom')  as nodep on department.id = nodep.nodepid

where nodepid is null;