У меня есть следующие данные:Неожиданные результаты с LAST_VALUE, CURRENT ROW, нулям
CREATE TABLE #Transfers (
AddedOn DATETIME2 NOT NULL,
EmpID INT NOT NULL,
NewDeptID INT NULL
)
INSERT INTO #Transfers
VALUES
('2013-12-17 17:18:54.3499987', 19, 36),
('2013-12-18 13:02:34.1168087', 19, NULL),
('2014-01-28 11:41:55.8755928', 22, 100),
('2014-02-05 10:36:36.3645703', 22, NULL),
('2014-02-16 00:00:00.0000000', 22, 37),
('2014-02-17 00:00:00.0000000', 22, NULL)
Для каждой строки, я стараюсь, чтобы получить самую последнюю непустой NewDeptID
(до этой строки):
SELECT *,
LAST_VALUE(NewDeptID) OVER (
PARTITION BY EmpID
ORDER BY IIF(NewDeptID IS NULL,0,1), AddedOn
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS CurrentDeptID
FROM #Transfers
ORDER BY EmpID, AddedOn
Если я правильно понимаю, нулевые значения должны быть исключены, поскольку они являются первыми значениями в окне - IIF(NewDeptID IS NULL,0,1)
.
Я хотел бы ожидать следующее:
AddedOn EmpID NewDeptID CurrentDeptID
2013-12-17 17:18:54.3499987 19 36 36
2013-12-18 13:02:34.1168087 19 NULL 36
2014-01-28 11:41:55.8755928 22 100 100
2014-02-05 10:36:36.3645703 22 NULL 100
2014-02-16 00:00:00.0000000 22 37 37
2014-02-17 00:00:00.0000000 22 NULL 37
Вместо этого предложения ORDER BY внутри LAST_VALUE игнорируется, и NULL возвращается, если текущая строка содержит NULL:
AddedOn EmpID NewDeptID CurrentDeptID
2013-12-17 17:18:54.3499987 19 36 36
2013-12-18 13:02:34.1168087 19 NULL NULL --
2014-01-28 11:41:55.8755928 22 100 100
2014-02-05 10:36:36.3645703 22 NULL NULL --
2014-02-16 00:00:00.0000000 22 37 37
2014-02-17 00:00:00.0000000 22 NULL NULL --
Я получаю те же результаты в SQL Server 2012 и 2014.
Является ли это ошибкой в SQL Server, или я что-то пропускаю в синтаксисе функции окна?
Примечание: Если я развернуть окно, чтобы включить весь раздел, нули игнорируются:
SELECT *,
LAST_VALUE(NewDeptID) OVER (
PARTITION BY EmpID
ORDER BY IIF(NewDeptID IS NULL,0,1), AddedOn
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS CurrentDeptID
FROM #Transfers
ORDER BY EmpID, AddedOn
Результаты:
AddedOn EmpID NewDeptID CurrentDeptID
2013-12-17 17:18:54.3499987 19 36 36
2013-12-18 13:02:34.1168087 19 NULL 36
2014-01-28 11:41:55.8755928 22 100 37
2014-02-05 10:36:36.3645703 22 NULL 37
2014-02-16 00:00:00.0000000 22 37 37
2014-02-17 00:00:00.0000000 22 NULL 37
Я не понимаю. Если сначала применяется «ORDER BY», тогда записи с нулевыми значениями сначала входят в раздел. При вычислении последнего значения в пределах раздела до текущей строки результат никогда не должен быть нулевым, если значение для всех предыдущих записей в разделе также не равно нулю. –
Но вы сказали так: * «записи с нулевыми значениями сначала входят в раздел» *. Если строка имеет нуль, все строки перед ней также имеют нуль. И когда я написал «ORDER BY», я имел в виду «ORDER BY IIF ...», а не внешний порядок. –
Ваш 'IIF()' не позволяет этого (все строки с нулевым размещением после всех строк с нулевым). Я отредактировал свой ответ с подробностями о том, как работают окна. –