ROW_NUMBER() 仅适用于前 N 条记录



我有一个方案来获取基于Id列的结果集的零索引值。我可以通过ROW_NUMBER()来实现这一点.但是现在预期的行为略有变化。

期望是,对于前五条记录,只需要显示IndexValue,对于其余条目,应NULLIndexValue

为了实现这一点,我通过ROW_NUMBER()设置了IndexValue@PopulateValues推送到表变量中,然后使用UPDATE得到预期的结果,如下所示:

我尝试过的:

-- Actual Table in database
DECLARE @OriginalTable TABLE (Id INT IDENTITY(1, 1), [Name] VARCHAR (255));
INSERT INTO @OriginalTable ([Name]) VALUES 
('Name 01'), ('Name 02'), ('Name 03'), ('Name 04'), ('Name 05'), 
('Name 06'), ('Name 07'), ('Name 08'), ('Name 09'), ('Name 10'), 
('Name 11'), ('Name 12'), ('Name 13'), ('Name 14'), ('Name 15');
-- Table variable for the populate calculation
DECLARE @PopulateValues TABLE (Id INT, [Name] VARCHAR (255), IndexValue INT NULL);
INSERT INTO @PopulateValues (Id, [Name], IndexValue)
SELECT Id, [Name], ROW_NUMBER() OVER (ORDER BY Id) - 1 AS IndexValue
FROM @OriginalTable;
UPDATE @PopulateValues SET IndexValue = NULL WHERE IndexValue >= 5;
SELECT * FROM @PopulateValues;

通过这种方法,我能够实现我的期望,但是有没有其他方法可以在SELECT时仅将ROW_NUMBER()应用于TOP N记录?

您可以在查询中使用case表达式:

SELECT Id, Name, CASE WHEN IndexValue < 5 THEN IndexValue END AS IndexValue
FROM   (SELECT Id, Name, ROW_NUMBER() OVER (ORDER BY Id) - 1 AS IndexValue
FROM   @OriginalTable) t

您可以使用 CASE 语句和子查询,如下所示:

INSERT INTO @PopulateValues (Id, [Name], IndexValue)
SELECT x.[Id], x.[Name], CASE WHEN x.IndexValue < 5 THEN x.IndexValue ELSE NULL END AS [IndexValue]
FROM
(
SELECT Id, [Name], ROW_NUMBER() OVER (ORDER BY Id) - 1 AS IndexValue
FROM @OriginalTable;
) AS x

由于我找到了使用逻辑函数 - IIF(从 SQL Server 2012 开始(的另一种可能方法,因此查询将是:

SELECT Id, [Name], IIF(IndexValue < 5, IndexValue, NULL) AS IndexValue 
FROM  ( SELECT Id, Name, ROW_NUMBER() OVER (ORDER BY Id) - 1 AS IndexValue
FROM @OriginalTable ) Q

最新更新