是否可以按日期/时间拆分轮班记录

时间:2019-01-29 05:47:54

标签: sql-server tsql

我拥有具有夜班记录的花名册数据(例如,开始时间为2019-01-30 21:00:00.000,结束时间为第二天2019-01-31 05:30:00.000。

我需要将其分成两行,如下所示

  

2019-01-30 21:00:00.000至2019-01-30 23:59:59.999

     

2019-01-31 00:00:00.001至2019-01-31 05:30:00.000

我需要保留该行中的所有其他信息。而日期是轮班开始的日期。

    SELECT  actual_id
            , emp_id
            , emp_number
            , area
            , area_id
            , day_date
            , start_time
            , finish_time

    FROM Roster
WHERE CONVERT(date,start_time, 112) <> CONVERT(date,finish_time, 112)

enter image description here

2 个答案:

答案 0 :(得分:0)

要创建两行,您可以CROSS JOIN使用一个临时表,该临时表具有如下两行。

select *
FROM roster 
INNER JOIN 
           ( 
                  SELECT 1 temp 
                  UNION 
                  SELECT 2 temp )t 
    ON  1=1 

以上查询将每行复制两次。

现在基于行号(1或2),您可以获取一天的结束时间和一天的开始时间,例如

 CASE  WHEN t.rownum =1 THEN start_time 
        ELSE dateadd(second, 1, Dateadd(day, Datediff(day, 0, finish_time), 0) 
       end starttime , 
 CASE 
     WHEN t.rownum=2 THEN finish_time 
        ELSE dateadd(ms, -2, dateadd(dd, 1, datediff(dd, 0, start_time))) 
     END AS endtime FROM roster 

您的最终查询应类似于以下查询。

SELECT     actual_id , 
           emp_id , 
           emp_number , 
           area , 
           area_id , 
           day_date , 
           CASE 
                      WHEN t.rownum=1 THEN start_time 
                      ELSE dateadd(second, 1, Dateadd(day, Datediff(day, 0, finish_time), 0) 
           end starttime , 
           CASE 
                      WHEN t.rownum=2 THEN finish_time 
                      ELSE dateadd(ms, -2, dateadd(dd, 1, datediff(dd, 0, start_time))) 
           END AS endtime FROM roster 
INNER JOIN 
           ( 
                  SELECT 1 rownum
                  UNION 
                  SELECT 2 rownum)t 
    ON  1=1 
WHERE CONVERT(date,start_time, 112) <> CONVERT(date,finish_time, 112)

答案 1 :(得分:0)

请尝试上述解决方案:

SELECT
  s.emp_id,
  f.theDay
FROM Roster AS s
CROSS APPLY (SELECT
  DATEADD(DAY, Number, s.start_time)
FROM master..spt_values AS v
WHERE v.Type = 'P'
AND v.Number BETWEEN 0 AND DATEDIFF(DAY, s.start_time, s.finish_time)) AS f (theDay)
ORDER BY s.emp_id,
f.theDay