Sql 查找A班和B班所有注册学生的姓名
基于下面的模式,其中 主键是sid和cid。表模式如下所示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:integer,姓名:string,专业:string,年龄:integer)
- 注册(sid:整数,cid:整数)
- 类(cid:整数,名称:字符串,讲师:字符串,房间:字符串,时间:时间)
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
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;