假设我有三张桌子
Student Student_Interest Interest
======= ================ ========
Id Student_Id Id
Name Interest_Id Name
Student_Interest.Student_Id指的是Student.Id 和Student_Interest.Interest_Id指的是Interest.Id
假设我们有三种兴趣即。 “Java”,“C”,“C ++”和“C#”,学生表中有一些条目以及Student_Interest表中各自的兴趣映射条目。 (典型的多对多关系)
我们如何才能获得同时兼顾“Java”和“C”的学生名单?
答案 0 :(得分:1)
只需从student_interest获取Java和C记录,按学生分组,看看您是否获得了学生的完整兴趣数量。通过这些学生发现,您可以显示学生表中的数据。
select *
from student
where id in
(
select student_id
from student_interest
where interest_id in (select id from interest where name in ('Java', 'C'))
group by student_id
having count(distinct interest_id) = 2
);
编辑:您已经让我用EXISTS显示查询。直截了当的方式是:
select *
from student
where exists
(
select *
from student_interest
where student_id = student.id
and interest_id = (select id from interest where name = 'Java')
)
and exists
(
select *
from student_interest
where student_id = student.id
and interest_id = (select id from interest where name = 'C')
);
对于每个兴趣,还有一个额外的EXISTS条款。但是,如果要将上面的IN查询转换为EXISTS查询,那么只有一个EXISTS子句,则得到:
select *
from student
where exists
(
select student_id
from student_interest
where student_id = student.id
and interest_id in (select id from interest where name in ('Java', 'C'))
group by student_id
having count(distinct interest_id) = 2
);
我发现IN子句更具可读性,但我认为这是一种品味问题。
答案 1 :(得分:1)
我已经看到了几个正确答案,但无论如何,这是我的答案:
select s.* from student s
join (
select si.student_id from student_interest si join interest i on i.id = si.interest_id
where i.name in ('Java','C') group by si.student_id having count(*) = 2
) iv on iv.student_id = s.id
答案 2 :(得分:0)
您需要加入所有三个表格以获取如下信息:
SELECT s.*
FROM Student s, Student_Interest si, Interest i, Interest sin
WHERE s.Id = si.Student_Id
AND i.Id = si.Interest_Id
AND sin.Id = si.Interest_Id
AND i.Name = 'Java'
AND sin.Name = 'C'
答案 3 :(得分:0)
对所有表格执行JOIN
。您需要GROUP BY
列Name
才能获得如下所示的兴趣。查看演示小提琴http://sqlfiddle.com/#!2/e80391/13
select s.Name
from student s
join Student_Interest si on s.id = si.Student_Id
join Interest i on si.Interest_Id = i.id
join Interest ii on si.Interest_Id = ii.id
group by s.Name
having count(*) > 1
答案 4 :(得分:0)
我们如何获得同时具有“Java”和“C”的学生列表 他们的兴趣?
我们可以写t(t.c,...)来表示行(t.c,...)在表t中。让别人学生为s,学生_Interest为sij和sic以及对ij和ic的兴趣。我们想要行(s.Id,s.Name)其中
s(s.Id,s.Name)
AND sij(sij.Student_Id,sij.Interest_Id) AND s.Id = sij.Student_Id
AND sic(sic.Student_Id,sic.Interest_Id) AND s.Id = sic.Student_Id
AND ij(ij.Id,ij.Name) AND ij.Id=sij.Interest_Id AND ij.Name = 'Java'
AND ic(ic.Id,ic.Name) AND ic.Id=sic.Interest_Id AND ic.Name = 'C'
所以:
select s.Id,s.Name
from Student s
join Student_Interest sij on s.Id = sij.Student_Id
join Student_Interest sic on s.Id = sic.Student_Id
join Interest ij on ij.Id=sij.Interest_Id AND ij.Name = 'Java'
join Interest ic on ic.Id=sic.Interest_Id AND ic.Name = 'C'