我有一个这样的架构:
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表是用户信息。 School表是学校信息。学生表将学校与用户链接起来。我想选择所有不包含“ 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/
答案 0 :(得分:2)
您可以尝试以下方法:
SELECT *
FROM School
WHERE id NOT IN (SELECT SchoolId
FROM Student
JOIN AppUser
ON Student.UserId = AppUser.id
AND name = 'sashan')
方括号之间的查询选择所有学校“ sashan”在其中。
选择所有不属于这些学校的学校,即可得到您所要求的学校。
答案 1 :(得分:1)
我会使用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;
答案 2 :(得分:1)
您做对了。这是使用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)
如果索引正确,那么这两个查询应该都能很好地工作