每个组中排名前2位的SQL Server

时间:2018-08-08 14:26:43

标签: sql-server

我有8条记录

Name        Value  Product
--------------------------
Abraham       4        A
Lincoln       6        B
Abraham       4        C
Lincoln       2        D
Lincoln       3        E
Lincoln       2        F
Abraham       1        G
Abraham       9        H     

亚伯拉罕和林肯也有4条记录。

从SQL中,我需要Abraham的前2个值和Lincoln的前2个值

我尝试过:

SELECT TOP 2 WITH TIES 
    NAME,
    VALUE,
    PRODUCT
FROM
    blabla
JOIN
    blabla...
ORDER BY 
    NAME

这需要每个名字2个,但不是最贵重的,因为我没有按desc设置VALUE顺序。

但是由于联系最多,所以我无法按desc排列VALUE顺序。

我需要的是使“ TOP WITH TIES”仅适用于按名称排序(如果可以这样做,例如将具有顶部的关系限制为一阶),但是我只需要最大2个它们的值。

我需要的最终结果:

Abraham       9        H   
Abraham       4        C
Lincoln       6        B
Lincoln       3        E

PS:这只是我想要的模拟,原始查询有超过100行包含并集和内容的行,因此我认为最好简化一下。

2 个答案:

答案 0 :(得分:0)

您可以使用ROW_NUMBER和分区来做到这一点。

select Name
    , Value
    , Product
from
(
    select Name
        , Value
        , Product
        , RowNum = ROW_NUMBER() over(partition by Name order by value desc)
    from SomeTable
) x
where x.RowNum <= 2
order by x.Name
    , x.Value desc

答案 1 :(得分:0)

一个解决方案是使用CROSS APPLYTOP的{​​{1}}。您从名称列表开始,然后调用“ function ”,该函数为每个名称返回ORDER BY

TOP

请记住,在存在值关系的情况下,使用SELECT N.Name, V.Value, V.Product FROM (SELECT DISTINCT Y.Name FROM YourTable AS Y) AS N CROSS APPLY ( SELECT TOP 2 WITH TIES P.Value, P.Product FROM YourTable AS P WHERE N.Name = P.Name ORDER BY P.Value DESC ) AS V 可使WITH TIES返回的行数超过提供的行数(在您的示例中为2)。

如果您需要显示没有产品的名称(在此示例中,由于两个名称都来自同一表格,因此将无法使用),则可以将TOP切换为CROSS APPLY,的行为与OUTER APPLY相似,因为它将返回LEFT JOIN值(而不是2行!)。