我有一个看起来像这样的表:
Name Group Value
A 1 0
B 1 2
C 1 5
D 2 6
E 2 0
F 3 3
Run Code Online (Sandbox Code Playgroud)
我想选择每组中具有最大值的名称。例如,有 3 个组,因此结果将是:
Name
C (because it has the maximum value (5) within group 1)
D (because it has the maximum value (6) within group 2)
F (because it has the maximum value (3) within group 3)
Run Code Online (Sandbox Code Playgroud)
我尝试写这样的东西:
SELECT name FROM table
WHERE value = (SELECT max(value) FROM table)
GROUP BY group
Run Code Online (Sandbox Code Playgroud)
但 max(value) 返回整个表的全局最大值(如本例中的 (6))。我该如何解决?
Sql*_*Zim 12
有很多方法可以做到这一点,以下是其中一些:
rextester 适用于所有这些:http ://rextester.com/DTWB67044
max()
over()
版本:
with cte as (
select *, MaxValue = max([Value]) over (partition by [Group])
from t
)
select Name
from cte
where [Value] = MaxValue;
Run Code Online (Sandbox Code Playgroud)
inner join
版本:
select t.Name
from t
inner join (
select MaxValue=max(value), [Group]
from t
group by [Group]
) as m
on t.[Group] = m.[Group]
and t.[Value] = m.MaxValue;
Run Code Online (Sandbox Code Playgroud)
select t.Name
from t
cross apply (
select top 1
[Value]
from t as i
where i.[Group] = t.[Group]
order by i.[Value] desc
) as x
where t.[Value] = x.[Value];
Run Code Online (Sandbox Code Playgroud)
如果您只为每组返回一个值,这些也可以工作:
with cte as (
select *, rn = row_number() over (partition by [Group] order by [Value] desc)
from t
)
select Name
from cte
where rn = 1;
Run Code Online (Sandbox Code Playgroud)
select top 1 with ties
t.Name
from t
order by row_number() over (partition by [Group] order by [Value] desc);
Run Code Online (Sandbox Code Playgroud)
你们有点接近。您需要一个相关子查询而不是外部查询中的聚合:
SELECT t.*
FROM table t
WHERE value = (SELECT max(t2.value) FROM table t2 WHERE t2.group = t.group);
Run Code Online (Sandbox Code Playgroud)
这是标准 SQL,适用于任何数据库。name
如果这就是您想要的,您可以选择,但我认为这group
也会很有用。
在大多数数据库中,您将用于row_number()
此目的。
在 SQL Server 中,更典型的做法是:
select t.*
from (select t.*,
row_number() over (partition by group order by value desc) as seqnum
from t
) t
where seqnum = 1;
Run Code Online (Sandbox Code Playgroud)
如果存在平局(对于最大值),则仅返回一行(通常是所需的行)。如果您想要所有此类行,请使用rank()
或dense_rank()
代替。