选择不在使用多个连接语句创建的表中的行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选择不在使用多个连接语句创建的表中的行相关的知识,希望对你有一定的参考价值。

我有这样的架构:

create table AppUser (id int, name varchar(255));
insert into AppUser (id, name) values ('1','sashan');
insert into AppUser (id, name) values ('2','someone');
insert into AppUser (id, name) values ('3','mckenzie');
create table school (id int, name varchar(255));
insert into School (id, name) values ('1','pascoe high');
insert into School (id, name) values ('2','highbury');
insert into School (id, name) values ('3','hilton');
insert into School (id, name) values ('4','melbourne girls');
create table Student(SchoolId int, UserId int);
insert into Student (SchoolId, UserId) values ('2','1');
insert into Student (SchoolId, UserId) values ('3','1');
insert into Student (SchoolId, UserId) values ('4','3');

AppUser表是用户信息。学校表是学校信息。学生表将学校与用户联系起来。我想选择所有'sashan'不在的学校。

我想出来了:

select *
from School
left join Student
       on Student.SchoolId = School.Id
left join AppUser
       on AppUser.id = Student.userid
where AppUser.name is null
   or AppUser.name != 'sashan';

但是想知道是否有更好的方法。

如果你想重现表并使用这个问题中的代码测试sql,请参阅http://www.sqlfiddle.com/

答案

你可以试试这个:

SELECT *
FROM   School
WHERE  id NOT IN (SELECT SchoolId
                  FROM   Student
                  JOIN   AppUser
                    ON   Student.UserId = AppUser.id
                   AND   name = 'sashan')

括号内的查询选择所有学校'sashan'所在。 选择所有不属于这些学校的学校,您可以获得所要求的学校。

另一答案

你做得对。这是使用NOT EXISTS原因的替代版本

SELECT s.*
FROM school s
WHERE NOT EXISTS 
  (SELECT 1 
   FROM student st 
   JOIN AppUser au ON au.name != 'sashan' AND au.id = st.userId 
   WHERE s.id = st.schoolId)

如果你有正确的索引,那么这两个查询应该可以正常工作

另一答案

我会用not exists

select s.*
from School s 
where not exists (select 1
                  from Student st join
                       AppUser au
                       on au.id = st.userid
                  where st.SchoolId = s.Id and
                        au.name = 'sashan' 
                 );

你的版本不太正确,因为'sashan'上的条件需要在on条款中。所以相当于以上是:

select s.*
from School s left join
     Student st
     on st.SchoolId = s.Id left join
     AppUser au
     on au.id = st.userid and au.name = 'sashan'
where au.name is null;

以上是关于选择不在使用多个连接语句创建的表中的行的主要内容,如果未能解决你的问题,请参考以下文章

从表中的多个值中选择不在数组中的位置

无法从 SQLPLUS 中的 select 语句创建的表中选择数据

Mysql:从一个表中选择不在另一个表中的行

从 id 不在 id 列表中的表中选择

如何使用 MySQL 连接语句选择与链接表中的多个值匹配的记录?

ORACLESQL语句的优化