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

时间:2018-09-19 13:26:58

标签: sql sql-server select row-number

我有一种方案可以根据Id列获取结果集的零索引值。我可以通过ROW_NUMBER()来实现。但是,现在的预期行为略有变化。

对于前五条记录,仅需要显示IndexValue,对于其余条目,IndexValue应该为NULL

要实现这一点,我用IndexValue设置了ROW_NUMBER(),将其放入表变量@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;

通过这种方法,我能够达到我的期望,但是还有其他方法可以将ROW_NUMBER()上的TOP N记录仅应用SELECT吗?

3 个答案:

答案 0 :(得分:6)

您可以在查询中使用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

答案 1 :(得分:2)

您可以将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

答案 2 :(得分:2)

我发现使用Logical Function - 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