SQL 选择另一列中具有最大值的列

use*_*285 8 sql sql-server

我有一个看起来像这样的表:

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)

cross apply()版本:

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)

如果您只为每组返回一个值,这些也可以工作:

带有版本的公共表表达式row_number()

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)

top with ties版本:

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)


Gor*_*off 5

你们有点接近。您需要一个相关子查询而不是外部查询中的聚合:

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()代替。