SQL使用row_number()或rank()选择具有最大值的行

时间:2017-03-10 19:53:56

标签: sql-server

我有以下类型的数据:

RowId   Name    Value
1       s1      12
22      s1      3
13      s1      4
10      s2      14
22      s2      5
3       s2      100

我希望得到以下输出:

RowId   Name    Value
1       s1      12
3       s2      100

我目前正在使用临时表来分两步完成。我一直在尝试使用row_number()和rank()函数,但还没有成功。

有人可以帮助我使用语法,因为我觉得row_number()和rank()会让它变得更干净吗?

编辑: 我更改了rowId以使其成为一般情况

编辑: 如果有任何想法,我比row_number()和rank()更受欢迎。

3 个答案:

答案 0 :(得分:4)

如果使用rank(),当名称包含多行且具有相同的最大值时,您可以获得多个结果。如果这是您想要的,请在以下示例中将row_number()切换为rank()

对于每value name最高{每组排名前1位},使用row_number()

select sub.RowId, sub.Name, sub.Value
from (
  select *
    , rn = row_number() over (
        partition by Name 
        order by Value desc
      )
  from t
  ) as sub
where sub.rn = 1

我不能说有更好的替代品,但也有其他选择。表现可能会有所不同。

cross apply 版本:

select distinct
    x.RowId
  , t.Name
  , x.Value
from t
  cross apply (
    select top 1
          *
      from t as i
      where i.Name = t.Name
      order by i.Value desc
    ) as x;

top with ties 使用row_number()版本:

select top 1 with ties
    *
  from t
  order by 
    row_number() over (
      partition by Name
      order by Value desc
      )

这个inner join版本与使用rank()代替row_number()的问题相同,因为如果名称包含多个相同的行,则可以获得相同名称的多个结果最大值。

inner join版本:

select t.*
from t
  inner join (
    select MaxValue = max(value), Name
    from t
    group by Name
    ) as m
      on t.Name  = m.Name
     and t.Value = m.MaxValue;

答案 1 :(得分:4)

如果您真的想使用ROW_NUMBER(),可以这样做:

With Cte As
(
    Select  *,
            Row_Number() Over (Partition By Name Order By Value Desc) RN
    From    YourTable
)
Select  RowId, Name, Value
From    Cte
Where   RN = 1;

答案 2 :(得分:0)

除非我遗漏了什么......为什么要使用row_number()或rank?

select rowid, name, max(value) as value
from table
group by rowid, name