sql-server - SQL 服务器 : splitting a row into several rows based off it's start and end date

标签 sql-server sql-server-2012

SQL Server:我有一个缺勤表,每个员工缺勤都有一个记录,其中有缺勤的开始和结束日期。例如

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

是否可以根据日期范围将行拆分为单独的行,以便缺席的每一天都有自己的行?提前致谢。

可能值得注意的是,这是源数据,将被转换为暂存区。

更新: 我还有一个小问题,你能帮忙吗?在我当前的表格中,还有一列显示因缺勤而丢失的轮类次数以及人员引用、开始和结束日期。目前,将记录分成几行代表每一天而不是一个时间范围意味着丢失的类次数列是重复的。例如在旧表中,如果某人休假 5 天并损失 3 个类次,则在新表中将有 3 行 - 每天一行 - 并且每天显示为 3 个类次损失。有办法拆分吗?

为了更好地解释这一点,表格过去看起来像这样:

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

谢谢

最佳答案

如果您没有日历表(强烈推荐),您可以将临时计数表与简单的 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])

返回

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-server - SQL 服务器 : splitting a row into several rows based off it's start and end date,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67007564/

相关文章:

c# - 启用 MS SQL Server 2012 的 TCP/IP 和 NamedPipe 协议(protocol) + 通过代码或脚本更改默认端口

sql-server - 排序规则与临时表冲突

sql - IsNull() 对 bigint 的最小值?

sql - 使用日期函数获取仅小于特定日期的日期

SQL 连接 - 识别缺失的行

sql - 使用 XML FOR 向 T-SQL 查询添加命名空间

ssis - 为什么我们需要SSIS和数据仓库的星型模式?

sql - 选择范围内的最小数字

sql-server - 模糊名称匹配算法

sql-server - 在 SQL 2008 中使用 Sequelize.js 进行分页(不支持 FETCH)