sql-server - SQL 服务器 : splitting a row into severa

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/

相关文章:

mongodb - 如何在 Rust 中使用 Mongodb::cursor?

ios - FaSTLane 设置 - 致命 : could not read Password f

javascript - 如何让 Bootstrap Toasts 不自动消失?

javascript - 如果没有 .js 扩展名,则为 ERR_MODULE_NOT_FOUND

javascript - SwiftUI:在 macOS 上与 WKWebView 的 Javasc

android - 如何在 Android 中更改 TextInputLayout 的 boxStr

validation - VeeValidate 4 : two forms on one page

python - 类型错误 : forward() takes 2 positional argum

java - 在 Spring Cloud Gateway 中获取真实的客户端 IP 地址

spring-boot - StreamingResponseBodyReturnValueHand