;WITH calcs AS (
-- 24 hours in seconds, minus 1 second for 23:59:59
SELECT CAST(24 * 60 * 60 - 1 AS INT) AS [t_const_1]
, CAST(2 * 24 * 60 * 60 - 1 AS INT) AS [t_const_2]
)
, timeCTE AS (
SELECT T.ID
, T.START_TIME AS [start_dt]
-- Find the "start" of the day (00:00:00) and add our constant
, DATEADD(SECOND, calcs.[t_const_1], CAST(CAST(T.START_TIME AS DATE) AS DATETIME)) AS [end_dt_1]
, T.END_TIME AS [end_dt]
FROM #_tmp AS T, calcs
UNION ALL
SELECT T1.ID
, DATEADD(HOUR, 24, CAST(CAST(T1.[end_dt_1] AS DATE) AS DATETIME)) AS [start_dt]
-- Find the "start" of the day (00:00:00) and add our constant times 2
, DATEADD(SECOND, calcs.[t_const_2], CAST(CAST(T1.[end_dt_1] AS DATE) AS DATETIME)) AS [end_dt_1]
, T1.[end_dt]
FROM timeCTE AS T1, calcs
WHERE CAST(T1.[end_dt_1] AS DATE) < CAST(T1.[end_dt] AS DATE)
)
, finalCTE AS (
SELECT T2.ID
, CONVERT(DATETIME, T2.[start_dt]) AS [start_dt]
, CASE
WHEN T2.[end_dt_1] > T2.[end_dt] THEN T2.[end_dt]
ELSE T2.[end_dt_1]
END AS [end_date]
FROM timeCTE AS T2
)
SELECT fin.[ID]
, CONVERT(DATETIME, fin.start_dt) AS [start_date]
, CONVERT(DATETIME, fin.end_date) AS [end_date]
, DATEPART(HOUR, fin.end_date) - DATEPART(HOUR, fin.[start_dt]) AS [net_daily_hours]
FROM finalCTE AS fin
Вывод:
ID start_dt end_date net_hours
01 2020-01-12 08:00:00.000 2020-01-12 23:59:59.000 15
02 2020-01-11 05:00:00.000 2020-01-11 23:59:59.000 18
02 2020-01-12 00:00:00.000 2020-01-12 23:59:59.000 23
02 2020-01-13 00:00:00.000 2020-01-13 02:00:00.000 2
01 2020-01-13 00:00:00.000 2020-01-13 23:59:59.000 23
01 2020-01-14 00:00:00.000 2020-01-14 08:00:00.000 8
В основном взяты из этого поста .