ROW_NUMBER () применяется только для первых N записей - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть сценарий, чтобы получить нулевое индексированное значение для набора результатов на основе столбца 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 голосов
/ 19 сентября 2018

Вы можете использовать оператор 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
0 голосов
/ 19 сентября 2018

Как я нашел еще один возможный способ, используя Логическая функция - 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
0 голосов
/ 19 сентября 2018

Вы можете использовать выражение 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
...