在起始和终止日期范围之间重复行

时间:2019-03-24 07:21:47

标签: sql-server

嗨,我正在使用“从”和“到”日期列中的休假表,没有应用任何天假。我想重复从“到”和“到”日期之间的行。

实际结果

leaveid fromdate    Todate       noofdays
1       01/01/2019  02/01/2019      2

例外结果

  leveid  fromdate      Todate      
     1     01/01/2019   01/01/2019 
      2    02/01/2019    02/01/2019

1 个答案:

答案 0 :(得分:1)

您可以使用master..[spt_values]生成所需的行数,并使用Dateadd生成如下的日期。

;with cte 
     as (select number 
         from   master..[spt_values] 
         where  type = 'p') 
select number+1 as leaveid, 
       Dateadd(day, number, fromdate) fromdate, 
       Dateadd(day, number, fromdate) todays 
from   @table t 
       inner join cte c 
               on c.number < t.noofdays 

Online Demo

如果您不想使用master..[spt_values],也可以像下面这样使用递归CTE

declare @maxNoOfDay int = (select max(noofdays) from @table)
;with seq( number ) as
(
    Select 0 as number
        union all
    Select number + 1
        from seq
        where number <= @maxNoOfDay
)

select number+1 as leaveid, 
       Dateadd(day, number, fromdate) fromdate, 
       Dateadd(day, number, fromdate) todays 
from   @table t 
       inner join seq c 
               on c.number < t.noofdays 

输出

+---------+-------------------------+-------------------------+
| leaveid | fromdate                | todays                  |
+---------+-------------------------+-------------------------+
| 1       | 2019-01-01 00:00:00.000 | 2019-01-01 00:00:00.000 |
+---------+-------------------------+-------------------------+
| 2       | 2019-01-02 00:00:00.000 | 2019-01-02 00:00:00.000 |
+---------+-------------------------+-------------------------+

编辑:

如果您希望日期采用特定格式,则可以使用CONVERT,如下所示。

declare @maxNoOfDay int = (select max(noofdays) from @table)
;with seq( number ) as
(
    Select 0 as number
        union all
    Select number + 1
        from seq
        where number <= @maxNoOfDay
)

select number+1 as leaveid, 
       convert(varchar, Dateadd(day, number, fromdate), 103)  fromdate, 
       convert(varchar, Dateadd(day, number, fromdate), 103) todays 
from   @table t 
       inner join seq c 
               on c.number < t.noofdays 

Online Demo

输出

+---------+------------+------------+
| leaveid | fromdate   | todays     |
+---------+------------+------------+
| 1       | 01/01/2019 | 01/01/2019 |
+---------+------------+------------+
| 2       | 02/01/2019 | 02/01/2019 |
+---------+------------+------------+