如何select先ROW_NUMBER结合SUM
How to select only first ROW_NUMBER combined with SUM
我喜欢在使用 SUM 时按 [ID] 对我的 table 进行分组,并带回
顶部 ROW_NUMBER
的 [Product_Name] - 不确定我是否应该使用 ROW_NUMBER
、GROUPING 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。
我喜欢在使用 SUM 时按 [ID] 对我的 table 进行分组,并带回
顶部 ROW_NUMBER
的 [Product_Name] - 不确定我是否应该使用 ROW_NUMBER
、GROUPING 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。