我最近在一次采访中被问到一个SQL问题。 要求是在包含学生ID,课程编号和年份的表格中找到“最热情的学生”。该查询应该返回每年参加课程最多的学生,并且只返回那些记录。(我有点忽略了不同学生在给定年份中学习相同课程数量的情况,因为我没有要求这样做可能会有其他要求来满足这种关系,所以我已经避免了这种情况,我只是专注于为每年没有同样热情的学生的特殊情况提供查询。
之后我建了一个小桌子来试图解决这个问题。 我的表有三个字段:
CREATE TABLE students (
student_no INT,
course_no INT,
year varchar(4));
(这是一个非常简单的表格。我知道这一年不应该像这样存储等等。我不想挂在桌子的格式上。这只是为了尽可能简单地支持练习。 )
我创建的数据是:
'1', '1', '2000'
'1', '2', '2000'
'1', '3', '2000'
'2', '1', '2000'
'2', '2', '2000'
'2', '3', '2000'
'2', '4', '2000'
'1', '2', '2001'
'1', '1', '2001'
'1', '3', '2001'
'1', '4', '2001'
'2', '1', '2001'
'2', '2', '2001'
'2', '3', '2001'
...所以学生2是2000年最热情的学生有4门课程**而学生1是2001年最热情的学生 4课程**。
'1', '4', '2001'
'2', '4', '2000'
我最终开始工作的问题是:
Select * from (
select max(coursecount), year from
(select student_no, count(course_no) as coursecount, year
from students
group by student_no, year) as internal group by year) as maxes,
(select student_no, count(course_no) as coursecount, year
from students
group by student_no, year) as students
where maxes.coursecount = students.coursecount
and maxes.year = students.year
......但我觉得有更好的方法可以做到这一点。
有人可以告诉我1)用ANSI SQL做更优雅的方法吗?2)用Oracle中的分析函数做另外一种方法吗?
提前感谢您的帮助。
答案 0 :(得分:1)
假设您使用的是SQL Server 2005 +
你可以尝试
;WITH Vals AS (
SELECT year, student_no, COUNT(course_no) Cnt
FROM students
GROUP BY year, student_no
)
, RowIDS AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY year ORDER BY CNT DESC) RowID
FROM Vals
)
SELECT *
FROM RowIDS
WHERE RowID = 1
答案 1 :(得分:0)
在标准SQL中,您可以尝试:
select year,student_no
from students
group by year,student_no
having count(*) = (
select max( cnt )
from (
select count(*) cnt
from students
group by year,student_no
) x
)