首页 > 解决方案 > 每组前 2 名订购了 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 仅适用于 ORDER BY NAME (如果有办法做到这一点,比如将顶部与第一个 order by 联系起来),但我只需要它们的 2 个最大值.

我需要的最终结果:

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

PS:这只是我想要的模拟,原始查询有超过 100 行的联合和东西,所以我认为最好简化。

标签: sql-server

解决方案


一个解决方案是一个CROSS APPLYwithTOPORDER 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可以使TOP返回的行数超过提供的行数(以您的示例为 2),以防存在值的联系。

如果您需要显示没有产品的名称(在此示例中它不起作用,因为两者都来自同一个表),您可以切换CROSS APPLYfor a OUTER APPLY,它的行为类似于 a LEFT JOIN,因为它会返回NULL值(但不是2 行!)。


推荐阅读