我有一个数据结构,学生和小组之间有多对多的关系。我有三张桌子
学生:id,姓名
groups:id,name
students_groups:student_id,group_id
如何仅选择不在特定群组中的学生(例如group.id = 1)?
我做了一些搜索并尝试使用子查询,但只获得一个空集......
select * from students where not exists (select students.* from students left join students_groups on students_groups.student_id = student.id where students_groups.group_id = 1);
我该如何查询?提前多了!
修改 好吧,似乎以下两个终于有效......任何人都可以解释为什么我不需要加入表来工作???
select * from students where not exists (select * from students_groups where students_groups.student_id = student.id and student_groups.group_id = 1);
select * from students where id not in (select student_id from students_groups where group_id = 1);
答案 0 :(得分:8)
使用NOT IN
应该可以正常工作:
SELECT * FROM Students
WHERE Id NOT IN (
SELECT Student_Id FROM Students_Groups
WHERE Group_Id = 1)
答案 1 :(得分:2)
您可以尝试这样的事情:
SELECT
*
FROM
students
WHERE
id NOT IN
((SELECT
student_id
FROM
students_groups
WHERE
group_id = 1
))
答案 2 :(得分:2)
编辑过的问题要求解释。
将SQL查询视为文本中的Venn Diagrams。每个子句都定义了一个内容圈,或者告诉您您感兴趣的完整重叠圆圈图的哪一部分。
select * from students where id not in (select student_id from students_groups where group_id = 1);
一个圈是学生表。一个圆圈是student_groups表,其中group_id = 1.圆圈重叠,其中students.id等于student_groups.student_id。您希望学生表的一部分在重叠区域中不。
您不需要加入表格,因为结果集仅包含来自学生表格的数据。您正在使用另一个表来限制结果集,而不是为结果提供数据。
答案 3 :(得分:1)
未经测试,但以下其中一项应该有效。你必须做一些explain
,看看哪一个是最好的。
select *
from students
where not exists (select *
from students_groups
where students_groups.student_id = student.id
and students_groups.group_id = 1)
...或
select *
from students
where id not in (select student_id
from students_groups
where group_id = 1)
...或
select students.id, students.name
from students
left outer join students_groups on students.id = students_groups.student_id
and students_groups.group_id = 1
where students_groups.student_id is null
group by students.id, students.name