将一列中的一个值与SQL中其他列中的多个值匹配

时间:2014-11-07 07:07:31

标签: mysql sql

假设我有三张桌子

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”的学生名单?

5 个答案:

答案 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 BYName才能获得如下所示的兴趣。查看演示小提琴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'