我Student
在 SQL Server 中有一个包含这些列的表:
[ID], [Age], [Level]
我希望查询返回出现在 中的每个年龄值Students
,并找到最常出现的级别值。例如,如果'a'
18 岁的水平学生多于 'b' 或 'c' 它应该打印 pair (18, a)
。
我是 SQL Server 的新手,我想要一个简单的嵌套查询答案。
我Student
在 SQL Server 中有一个包含这些列的表:
[ID], [Age], [Level]
我希望查询返回出现在 中的每个年龄值Students
,并找到最常出现的级别值。例如,如果'a'
18 岁的水平学生多于 'b' 或 'c' 它应该打印 pair (18, a)
。
我是 SQL Server 的新手,我想要一个简单的嵌套查询答案。
您可以使用窗口函数执行此操作:
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
子句选择最高值。
在平局的情况下,这仅返回其中一个值。如果您想要所有这些,请使用rank()
而不是row_number()
.
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)
这会在学生表中找到每个年龄和级别组合,并计算每个级别的出现次数。然后,对于每个年龄/级别组合,找到在该年龄/级别组合中出现次数最多的那个。返回该行的年龄和级别。
这具有不与 SQL Server 绑定的优势——它是普通的 SQL。但是,像 Gordon 指出的窗口函数可能在 SQL Server 上执行得更好。
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上的演示
另一种选择,但需要更高版本的 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