我拥有具有夜班记录的花名册数据(例如,开始时间为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)
答案 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