SQL Group-By和返回有限的结果

时间:2014-02-20 18:29:11

标签: sql

我最近在一次采访中被问到一个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中的分析函数做另外一种方法吗?

提前感谢您的帮助。

2 个答案:

答案 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

SQL Fiddle DEMO

答案 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
  )

演示:http://sqlfiddle.com/#!11/41d12/7