SQL-Server:继续最后一个值而不是 NULL,分区不正确
Posted
技术标签:
【中文标题】SQL-Server:继续最后一个值而不是 NULL,分区不正确【英文标题】:SQL-Server: Continue Last Value other then NULL, Incorrect Partition By 【发布时间】:2020-12-14 14:24:05 【问题描述】:我想在Last_EmployeeId
列中为每个RoomNumber
显示最后一个EmployeeId
。所以当有NULL
值时,我应该返回EmployeeId
而不是NULL
。下面的查询几乎可以解决Partition by value_partition
的问题,因为value_partition
为非空记录显示了不同的数字。但是,在某个点上,value_partition
对 NULL 和非 NULL 记录显示完全相同的数字(大约 3000 条记录之后)。因此,它也会为所有不相关的房间返回 EmployeeId
(正如您在下面粘贴的数据 sn-p 中看到的那样)。
我使用以下代码:
;WITH Rooms_Rank AS (
SELECT
Rooms.*
,ROW_NUMBER() OVER (PARTITION BY Rooms.RoomNumber ORDER BY Rooms.[Date]) -
ROW_NUMBER() OVER (PARTITION BY Rooms.RoomNumber, Rooms.beginDate ORDER BY Rooms.[Date]) AS Rnk--[Services].beginDate ORDER BY RoomDate.[Date]) AS Rnk
FROM Rooms
)
SELECT
[Date]
,RoomNumber
,EmployeeId
,value_partition
,first_value(EmployeeId) OVER (PARTITION BY value_partition ORDER BY [Date]) AS Last_EmployeeId
FROM (
SELECT *,
SUM(CASE WHEN EmployeeId is null THEN 0 ELSE 1 END) OVER (ORDER BY RoomNumber, CAST([Date] AS DATE)) AS value_partition
FROM Rooms_Rank
) AS q
ORDER BY [Date] ASC, RoomNumber
数据集的小样本(因为这个问题只出现在记录3000+之后)
Date | RoomNumber | EmployeeId | value_partition | Last_EmployeeId |
---|---|---|---|---|
2020-10-12 | 33 | 607 | 133 | 607 |
2020-10-12 | 34 | NULL | 136 | NULL |
2020-10-12 | 401 | NULL | 136 | NULL |
2020-10-12 | 71 | NULL | 223 | NULL |
2020-10-13 | 33 | 607 | 134 | 607 |
2020-10-13 | 34 | NULL | 136 | NULL |
2020-10-13 | 401 | NULL | 136 | NULL |
2020-10-13 | 71 | NULL | 223 | NULL |
2020-10-14 | 33 | 607 | 135 | 607 |
2020-10-14 | 34 | NULL | 136 | NULL |
2020-10-14 | 401 | NULL | 136 | NULL |
2020-10-14 | 71 | NULL | 223 | NULL |
2020-10-15 | 33 | 607 | 136 | 607 |
2020-10-15 | 34 | NULL | 136 | 607 |
2020-10-15 | 401 | NULL | 136 | 607 |
2020-10-15 | 71 | NULL | 223 | NULL |
2020-10-16 | 33 | NULL | 136 | 607 |
2020-10-16 | 34 | NULL | 136 | 607 |
2020-10-16 | 401 | NULL | 136 | 607 |
2020-10-16 | 71 | NULL | 223 | NULL |
如您所见,现在不仅RoomNumber
33,而且34 和401 继续显示607。
如何找到正确显示最后一个“EmployeeId”的方法?
有什么建议吗?
【问题讨论】:
【参考方案1】:我了解您希望在每个房间的基础上使用最后一个非null
employeeid
。如果 SQL Server 支持选项 ignore nulls
到窗口函数 lag()
,那将是直截了当的 - 唉,很少有数据库支持,SQL Server 不是其中之一。
相反,我们可以将其作为间隙和孤岛问题来解决。我们可以使用非空值的累积计数将记录分组,然后为每个组选择唯一的非空值:
select t.*,
max(employeeid) over(partition by roomnumber, grp order by date) as lastemployeeid
from (
select rr.*,
count(employeeid) over(partition by roomnumber order by date) grp
from rooms_rank rr
) rr
【讨论】:
以上是关于SQL-Server:继续最后一个值而不是 NULL,分区不正确的主要内容,如果未能解决你的问题,请参考以下文章
SQL-server'WEEKDAY'不是公认的内置函数名称[关闭]
SQL-Server:备份集包含一个数据库的备份,而不是现有的