sql查询查找最常出现的级别

时间:2013-06-01 15:01:43

标签: sql sql-server

我在SQL Server中有一个表Student,其中包含以下列:

[ID], [Age], [Level] 

我希望查询返回Students中显示的每个年龄值,并查找最常出现的级别值。例如,如果18岁以上的'a'级学生多于“b”或“c”,则应打印(18, a)对。{/ p>

我是SQL Server的新手,我想要一个嵌套查询的简单答案。

4 个答案:

答案 0 :(得分:5)

您可以使用窗口功能执行此操作:

select t.*
from (select age, level, count(*) as cnt,
             row_number() over (partition by age order by count(*) desc) as seqnum
      from student s
      group by age, level
     ) t
where seqnum = 1;

内部查询聚合数据以计算每个年龄的级别数。 row_number()列举了每个年龄段(partition by,具有最大的年龄)。然后where子句选择最高值。

在tie的情况下,这只返回其中一个值。如果您想要所有这些内容,请使用rank()代替row_number()

答案 1 :(得分:1)

with combinations as (
  select age, level, count(*) occurrences
  from Student
  group by age, level
)
select age, level
from combinations c
where occurrences = (select max(occurrences)
                     from combinations
                     where age = c.age)

这将查找Students表中的每个年龄和级别组合,并计算每个级别的出现次数。 然后,对于每个年龄/级别组合,找到该年龄/级别组合的出现次数最高的那个。返回该行的年龄和级别。

这样做的好处是不依赖于SQL Server - 它是纯粹的SQL。但是,像Gordon指出的窗口函数可能在SQL Server上表现更好。

答案 2 :(得分:1)

在ORDER BY子句中使用ROW_NUMBER排名函数的另一个选项。如果要返回两个或多个在有限结果集中最后一个位置的行,则使用WITH TIES。

SELECT TOP 1 WITH TIES age, level
FROM dbo.Student
GROUP BY age, level
ORDER BY ROW_NUMBER() OVER(PARTITION BY age ORDER BY COUNT(*) DESC)

或者查询的第二个版本使用每对年龄和级别的数量,以及每个年龄的计数对年龄和级别的最大值。

SELECT *
FROM (
      SELECT age, level, COUNT(*) AS cnt, 
             MAX(COUNT(*)) OVER(PARTITION BY age) AS mCnt
      FROM dbo.Student
      GROUP BY age, level
      )x
WHERE x.cnt = x.mCnt

SQLFiddle上的演示

答案 3 :(得分:1)

另一个选项但需要更高版本的sql-server:

;WITH x AS
(
SELECT  age, 
        level, 
        occurrences = COUNT(*) 
FROM    Student
GROUP BY age, 
        level
)
SELECT *
FROM   x x
WHERE  EXISTS (
              SELECT * 
              FROM   x y
              WHERE  x.occurrences > y.occurrences
              )

我意识到它并没有完全回答这个问题,因为它只返回年龄/级别组合,其中年龄有多个级别。

也许有人可以帮助修改它,因此它包括结果集中的单级年龄:http://sqlfiddle.com/#!3/d597b/9