如何select先ROW_NUMBER结合SUM

How to select only first ROW_NUMBER combined with SUM

我喜欢在使用 SUM 时按 [ID] 对我的 table 进行分组,并带回 顶部 ROW_NUMBER 的 [Product_Name] - 不确定我是否应该使用 ROW_NUMBERGROUPING SETS 或使用 FETCH 遍历所有内容...这就是我尝试的方法:

DECLARE @SampleTable TABLE 
                     (
                          [ID] INT, 
                          [Price] MONEY, 
                          [Product_Name] VARCHAR(50)
                     )

INSERT INTO @SampleTable 
VALUES (1, 100, 'Product_1'), (1, 200, 'Product_2'),
       (1, 300, 'Product_3'), (2, 500, 'Product_4'),
       (2, 200, 'Product_5'), (2, 300, 'Product_6');

SELECT
    [ID],
    [Product_Name],
    [Price],
    SUM([Price]) OVER (PARTITION BY [ID]) AS [Price_Total],
    ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [ID]) AS [Row_Number]
FROM
    @SampleTable T1

我想要的结果 - 只有两条记录:

1   Product_1   100.00   600.00     1
2   Product_4   500.00  1000.00     1

非常感谢任何帮助或指导。

更新: 我最终使用 Prateek Sharma 在他的评论中建议的内容,简单地用另一个 SELECT WHERE [Row_Number] = 1

包装查询
SELECT * FROM
(
    SELECT
        [ID]
        ,[Product_Name]
        ,[Price]
        ,SUM([Price]) OVER (PARTITION BY [ID]) AS [Price_Total]
        ,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [ID]) AS [Row_Number]
    FROM @SampleTable
) MultipleRows
WHERE [Row_Number] = 1

一个选项是使用 WITH TIES 子句。没有额外的字段 RN.

希望您有一个正确的序列号或日期,可以在 sum() over 或最后的 row_number() over

中使用

例子

SELECT Top 1 with ties *
 From (
        Select [ID]
              ,[Product_Name]
              ,[Price]
              ,SUM([Price]) OVER (PARTITION BY [ID]) AS [Price_Total]
        FROM @SampleTable T1
      ) A 
Order By  ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [Price_Total] Desc) 

Returns

ID  Product_Name    Price   Price_Total
1   Product_1       100.00  600.00
2   Product_4       500.00  1000.00

您应该有一个列,您将在其中执行 ORDER BY for ROW_NUMBER()。在这种情况下,如果您只想依赖 table 自索引,那么可以将 ID 列用于 ORDER BY。

因此您的查询是正确的,您可以使用它。

其他选项是使用 WITH TIES 子句。但是,如果您将 WITH TIES 子句与 ID 列上的 ORDER BY 一起使用,那么性能将非常差。 WITH TIES 仅当您具有明确定义的索引时才会表现良好。并且,然后可以将该索引列与 WITH TIES 子句一起使用。

SELECT TOP 1 WITH TIES *
FROM (
         SELECT [ID]
               ,[Product_Name]
               ,[Price]
               ,SUM([Price]) OVER (PARTITION BY [ID]) AS [Price_Total]
         FROM @SampleTable
     ) TAB
ORDER BY ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY <IndexedColumn> DESC)

这个查询可能对你有点帮助。但请记住,它也不会提供比您编写的查询更好的性能。它只是减少了代码行。

没有 "top ROW_NUMBER" 除非您有定义排序的列。

如果你只想为每个 id 指定任意行,你可以使用下面的方法。要确定性地选择一个,您需要按确定性的唯一标准进行排序。

DECLARE @SampleTable TABLE
(
ID             INT,
Price          MONEY,
Product_Name   VARCHAR(50),
INDEX cix CLUSTERED (ID)
);

INSERT INTO @SampleTable
VALUES      (1,100,'Product_1'),
            (1,200,'Product_2'),
            (1,300,'Product_3'),
            (2,500,'Product_4'),
            (2,200,'Product_5'),
            (2,300,'Product_6');


WITH T AS
(
SELECT *,
       OrderingColumn = ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM @SampleTable
)

SELECT ID,
       SUBSTRING(MIN(CONCAT(STR(OrderingColumn), Product_Name)), 11, 50)         AS Product_Name,
       CAST(SUBSTRING(MIN(CONCAT(STR(OrderingColumn), Price)), 11, 50) AS MONEY) AS Price,
       SUM(Price)                                                                AS Price_Total
FROM   T
GROUP  BY ID 

此计划非常有效,因为它能够使用按 id 排序的索引,并且没有额外的排序、假脱机或通过 table。