Sql 查找A班和B班所有注册学生的姓名

Sql 查找A班和B班所有注册学生的姓名,sql,Sql,基于下面的模式,其中 主键是sid和cid。表模式如下所示 学生(sid:integer,姓名:string,专业:string,年龄:integer) 注册(sid:整数,cid:整数) 类(cid:整数,名称:字符串,讲师:字符串,房间:字符串,时间:时间) 学生将以sid和cid列在登记表中,该学生也将以相同的sid列在学生表中。cid将来自Classes表 我很难找到所有同时参加“A”和“B”课程的学生的名字。其中A&B是类名的字符串 SELECT S.name FROM Stude

基于下面的模式,其中

主键是sid和cid。表模式如下所示

  • 学生(sid:integer,姓名:string,专业:string,年龄:integer)

  • 注册(sid:整数,cid:整数)

  • 类(cid:整数,名称:字符串,讲师:字符串,房间:字符串,时间:时间)

学生将以sid和cid列在登记表中,该学生也将以相同的sid列在学生表中。cid将来自Classes表

我很难找到所有同时参加“A”和“B”课程的学生的名字。其中A&B是类名的字符串

SELECT S.name FROM Students S JOIN Classes C JOIN Enrollment E ON C.name = "A" AND C.name = "B"

您可以使用聚合和
HAVING
子句:

SELECT Sid, S.name
FROM Students S JOIN
     Enrollment E
     USING (sid) JOIN
     Classes C
     USING (cid)
WHERE C.name IN ('A', 'B')
GROUP BY sid, S.name
HAVING COUNT(*) = 2;   -- "2" is the number of classes in the `IN` list
注:

  • 您需要在上使用
    ,或者在联接中使用
    子句
  • 字符串常量应使用单引号,而不是双引号
  • 这假设一个学生不止一次注册同一个班级。如果可能,则使用
    HAVING COUNT(DISTINCT c.name)=2
编辑:

对于“A”而不是“B”,您可以执行以下操作:

HAVING MIN(c.name) = 'A' and MIN(c.name) = MAX(c.name)

我根本不会加入。您需要学生表中的行,因此从学生表中选择
。您希望满足一个条件,因此使用
WHERE
。至于在其他表中查找数据,您可以使用
中的
存在的

select name 
from students
where sid in
(
  select sid from enrollment where cid = (select cid from classes where name = 'A')
)
and sid in
(
  select sid from enrollment where cid = (select cid from classes where name = 'B')
)
order by name;

关于
子句的
在哪里?intersect不是更有效吗?可能不是,但值得比较这两种方法
INTERSECT
有删除重复项的开销,这本质上是一个
分组依据
。此外,它还多次执行
连接。我一直对sql中的集合操作有很好的看法。但最终我想解释计划是最后一个word@Raymond . . . 哎呀。来自的
中的顺序错误。@Raymond。为此,我喜欢使用
have
的原因之一是,它很容易表达范围广泛的问题。我称这些为“集合中的集合”查询。这也是一个很好的答案,我也阅读了你的陈述。感谢您的支持和替代方法。
select name 
from students
where sid in
(
  select sid from enrollment where cid = (select cid from classes where name = 'A')
)
and sid in
(
  select sid from enrollment where cid = (select cid from classes where name = 'B')
)
order by name;