SQL 服务器:根据开始日期和结束日期将一行分成几行
SQL Server : splitting a row into several rows based off it's start and end date
SQL 服务器:我有一个缺勤 table 每个员工缺勤都有一个记录,其中有缺勤的开始和结束日期。例如
Person Ref Start Date End Date
---------------------------------------
1234 01/01/2021 05/01/2021
我想根据日期范围将这一行分成几行,这样一来,每一行都代表缺席,而不是一行代表缺席,就像这样:
Person Ref Start Date End Date
------------------------------------
1234 01/01/2021 01/01/2021
1234 02/01/2021 02/01/2021
1234 03/01/2021 03/01/2021
1234 04/01/2021 04/01/2021
1234 05/01/2021 05/01/2021
是否可以根据日期范围将行拆分为单独的行,以便缺席的每一天都有自己的行?提前致谢。
可能值得注意的是,这是源数据,将被转换为临时区域。
更新:
我还有一个小问题,你能帮忙吗?在我当前的 table 中,还有一列显示因缺勤而丢失的轮班次数以及人员参考、开始和结束日期。目前,将记录分成几行代表每一天而不是一个时间范围意味着丢失的班次数列是重复的。例如在旧的 table 中,如果某人休假 5 天并损失 3 个班次,在新的 table 中将有 3 行 - 每天一行 - 并且每天显示为损失 3 个班次。有办法拆分吗?
为了更好地解释这一点,table 过去看起来像这样:
Person Ref Start Date End Date Shifts Lost
--------------------------------------------------
1234 01/01/2021 05/01/2021 3
现在看起来像这样(由于拆分我们已经完成了)
Person Ref Start Date End Date Shifts Lost
--------------------------------------------------
1234 01/01/2021 01/01/2021 3
1234 02/01/2021 02/01/2021 3
1234 03/01/2021 03/01/2021 3
1234 04/01/2021 04/01/2021 3
1234 05/01/2021 05/01/2021 3
有没有办法拆分行之间丢失的 3 个班次的计数?由于班次模式,缺勤 5 天的人不一定会错过 5 个班次,在这种情况下他们会错过 3 个班次。有没有办法让它像:
Person Ref Start Date End Date Shifts Lost
--------------------------------------------------
1234 01/01/2021 01/01/2021 1
1234 02/01/2021 02/01/2021 1
1234 03/01/2021 03/01/2021 1
1234 04/01/2021 04/01/2021 0
1234 05/01/2021 05/01/2021 0
谢谢
如果您没有日历 Table(强烈推荐),您可以使用临时计数 table 配合简单的 JOIN。
你可能注意到Top 1000
,这个可以调整到更合理的水平。
示例或dbFiddle
Select [Person Ref]
,[Start Date] = dateadd(DAY,N,[Start Date])
,[End Date] = dateadd(DAY,N,[Start Date])
From YourTable A
Join (
Select Top 1000 N=-1+Row_Number() Over (Order By (Select Null))
From master..spt_values n1,master..spt_values n2
) B on N <= datediff(DAY,[Start Date],[End Date])
Returns
Person Ref Start Date End Date
1234 2021-01-01 2021-01-01
1234 2021-01-02 2021-01-02
1234 2021-01-03 2021-01-03
1234 2021-01-04 2021-01-04
1234 2021-01-05 2021-01-05
更新 --- 班次丢失
Select [Person Ref]
,[Start Date] = dateadd(DAY,N,[Start Date])
,[End Date] = dateadd(DAY,N,[Start Date])
,[Shifts Lost]= case when N<[Shifts Lost] then 1 else 0 end
From YourTable A
Join (
Select Top 10000 N=-1+Row_Number() Over (Order By (Select Null))
From master..spt_values n1,master..spt_values n2
) B on N <= datediff(DAY,[Start Date],[End Date])
结果
Person Ref Start Date End Date Shifts Lost
1234 2021-01-01 2021-01-01 1
1234 2021-01-02 2021-01-02 1
1234 2021-01-03 2021-01-03 1
1234 2021-01-04 2021-01-04 0
1234 2021-01-05 2021-01-05 0
SQL 服务器:我有一个缺勤 table 每个员工缺勤都有一个记录,其中有缺勤的开始和结束日期。例如
Person Ref Start Date End Date
---------------------------------------
1234 01/01/2021 05/01/2021
我想根据日期范围将这一行分成几行,这样一来,每一行都代表缺席,而不是一行代表缺席,就像这样:
Person Ref Start Date End Date
------------------------------------
1234 01/01/2021 01/01/2021
1234 02/01/2021 02/01/2021
1234 03/01/2021 03/01/2021
1234 04/01/2021 04/01/2021
1234 05/01/2021 05/01/2021
是否可以根据日期范围将行拆分为单独的行,以便缺席的每一天都有自己的行?提前致谢。
可能值得注意的是,这是源数据,将被转换为临时区域。
更新: 我还有一个小问题,你能帮忙吗?在我当前的 table 中,还有一列显示因缺勤而丢失的轮班次数以及人员参考、开始和结束日期。目前,将记录分成几行代表每一天而不是一个时间范围意味着丢失的班次数列是重复的。例如在旧的 table 中,如果某人休假 5 天并损失 3 个班次,在新的 table 中将有 3 行 - 每天一行 - 并且每天显示为损失 3 个班次。有办法拆分吗?
为了更好地解释这一点,table 过去看起来像这样:
Person Ref Start Date End Date Shifts Lost
--------------------------------------------------
1234 01/01/2021 05/01/2021 3
现在看起来像这样(由于拆分我们已经完成了)
Person Ref Start Date End Date Shifts Lost
--------------------------------------------------
1234 01/01/2021 01/01/2021 3
1234 02/01/2021 02/01/2021 3
1234 03/01/2021 03/01/2021 3
1234 04/01/2021 04/01/2021 3
1234 05/01/2021 05/01/2021 3
有没有办法拆分行之间丢失的 3 个班次的计数?由于班次模式,缺勤 5 天的人不一定会错过 5 个班次,在这种情况下他们会错过 3 个班次。有没有办法让它像:
Person Ref Start Date End Date Shifts Lost
--------------------------------------------------
1234 01/01/2021 01/01/2021 1
1234 02/01/2021 02/01/2021 1
1234 03/01/2021 03/01/2021 1
1234 04/01/2021 04/01/2021 0
1234 05/01/2021 05/01/2021 0
谢谢
如果您没有日历 Table(强烈推荐),您可以使用临时计数 table 配合简单的 JOIN。
你可能注意到Top 1000
,这个可以调整到更合理的水平。
示例或dbFiddle
Select [Person Ref]
,[Start Date] = dateadd(DAY,N,[Start Date])
,[End Date] = dateadd(DAY,N,[Start Date])
From YourTable A
Join (
Select Top 1000 N=-1+Row_Number() Over (Order By (Select Null))
From master..spt_values n1,master..spt_values n2
) B on N <= datediff(DAY,[Start Date],[End Date])
Returns
Person Ref Start Date End Date
1234 2021-01-01 2021-01-01
1234 2021-01-02 2021-01-02
1234 2021-01-03 2021-01-03
1234 2021-01-04 2021-01-04
1234 2021-01-05 2021-01-05
更新 --- 班次丢失
Select [Person Ref]
,[Start Date] = dateadd(DAY,N,[Start Date])
,[End Date] = dateadd(DAY,N,[Start Date])
,[Shifts Lost]= case when N<[Shifts Lost] then 1 else 0 end
From YourTable A
Join (
Select Top 10000 N=-1+Row_Number() Over (Order By (Select Null))
From master..spt_values n1,master..spt_values n2
) B on N <= datediff(DAY,[Start Date],[End Date])
结果
Person Ref Start Date End Date Shifts Lost
1234 2021-01-01 2021-01-01 1
1234 2021-01-02 2021-01-02 1
1234 2021-01-03 2021-01-03 1
1234 2021-01-04 2021-01-04 0
1234 2021-01-05 2021-01-05 0