有三个表格:
关于学生的表:s41071030(sno, sname, ssex, sage, sdept)
关于课程的表格:c41071030(cno, cname, cpno, credit)
关于选择课程的表格:sc41071030(sno, cno, grade)
现在,我想要选择sdept='CS'
和他或她选择了部门'CS'
中课程最多的学生的详细信息。
答案 0 :(得分:1)
与任何适度复杂的SQL语句一样,最好做“TDQD” - 测试驱动的查询设计。从问题的简单部分开始,将它们构建成更复杂的答案。
要了解CS部门每个学生的课程数量,我们写道:
SELECT S.Sno, COUNT(*) NumCourses
FROM s41071030 S
JOIN sc41071030 SC ON S.Sno = SC.Sno
WHERE S.Sdept = 'CS'
GROUP BY S.Sno;
我们现在需要找到NumCourses的最大值:
SELECT MAX(NumCourses) MaxCourses
FROM (SELECT S.Sno, COUNT(*) NumCourses
FROM s41071030 S
JOIN sc41071030 SC ON S.Sno = SC.Sno
WHERE S.Sdept = 'CS'
GROUP BY S.Sno
)
现在我们需要将该结果与子查询相结合,因此是时候进行CTE(公用表表达式)了:
WITH N AS
(SELECT S.Sno, COUNT(*) NumCourses
FROM s41071030 S
JOIN sc41071030 SC ON S.Sno = SC.Sno
WHERE S.Sdept = 'CS'
GROUP BY S.Sno
)
SELECT N.Sno
FROM N
JOIN (SELECT MAX(NumCourses) MaxCourses FROM N) M
ON M.MaxCourses = N.NumCourses;
我们需要获取学生的详细信息,因此我们将其加入学生表:
WITH N AS
(SELECT S.Sno, COUNT(*) NumCourses
FROM s41071030 S
JOIN sc41071030 SC ON S.Sno = SC.Sno
WHERE S.Sdept = 'CS'
GROUP BY S.Sno
)
SELECT S.*
FROM s41071030 S
JOIN N ON N.Sno = S.Sno
JOIN (SELECT MAX(NumCourses) MaxCourses FROM N) M
ON M.MaxCourses = N.NumCourses;
轻度测试的SQL:你被警告了。要进行测试,请运行组件查询,确保每次都能获得合理的结果。在上一个查询正常工作之前,请不要继续下一个查询。
请注意,课程表对您正在解决的查询并不重要。
另请注意,如果有几个学生都参加相同数量的课程,这可能会返回几行,而且这个数字是学生所服用的最大数字。 (因此,如果有3名学生各自参加7门课程,并且没有学生参加7门以上的课程,那么您将在结果集中看到3行。)
答案 1 :(得分:1)
汇总sc41071030
行以获取计数。
将结果加入s41071030
:
过滤sdept
;
获取学生详细信息;
RANK()
计数值上的已加入行。
选择排名为1的行。
WITH
aggregated AS (
SELECT
sno,
COUNT(*) AS coursecount
FROM
sc41071030
GROUP BY
sno
),
ranked AS (
SELECT
s.*,
RANK() OVER (ORDER BY agg.coursecount DESC) AS rnk
FROM
s41071030 s
INNER JOIN aggregated agg ON s.sno = agg.sno
WHERE
s.sdept = 'CS'
)
SELECT
sno,
sname,
ssex,
sage,
sdept
FROM
ranked
WHERE
rnk = 1
;