【发布时间】:2026-01-25 12:30:01
【问题描述】:
我有以下数据:
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
相反,LAST_VALUE 中的 ORDER BY 子句被忽略,当当前行包含 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 中的错误,还是我在窗口函数语法中遗漏了什么?
注意:如果我扩展窗口以包含整个分区,则忽略 NULL:
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
【问题讨论】:
标签: sql-server sql-server-2012 window-functions sql-server-2014