根据日期范围分隔日期之间的小时数

时间:2015-11-09 23:10:55

标签: sql-server-2012

跨越多天的分时数

我有这样的数据。

StartDate       EndDate
2015-10-05 20:00:00.000 2015-10-06 12:00:00.000

我需要将此数据按日期分割,如

2015-10-05 240 (4 hours)
2015-10-06 720 (12 hours)

我可以像这样分开第一个开始日期

        select (StartDate as date) as StartDate,
            DATEDIFF(minute, StartDate, dateadd(day, 1, Cast(StartDate as date))) as diff           
        from t

给了我

2015-10-05 240

获取结束日期的数据,如

        select 
            Cast(EndDate as date) as StartDate,
            DATEDIFF(minute, Cast(EndDate as date), EndDate) as diff                
        from t


2015-10-06 720

但我不确定如何在一个查询中完成所有操作。此外,开始和结束之间的时间差异可能超过一天差异,如此

StartDate       EndDate
2015-10-05 20:00:00.000 2015-10-08 12:00:00.000

我需要

2015-10-05 240
2015-10-06 1440
2015-10-07 1440
2015-10-06 720

感谢您寻找

2 个答案:

答案 0 :(得分:2)

这应该涵盖开始和结束时间在同一天并且没有天数限制

编辑:修复了结束日期计算错误的问题

declare @StartDate datetime, @EndDate datetime
set @StartDate = '2015-10-05 20:00'
set @EndDate = '2015-10-05 21:00'

;WITH cte AS
(
    SELECT cast(@StartDAte as date) StartDate, 
           cast(dateadd(day, 1, @StartDAte) as date) EndDate
    UNION ALL
    SELECT DATEADD(day, 1, StartDate) StartDate, 
           DATEADD(day, 2, StartDate) EndOfDate
    FROM   cte
    WHERE  DATEADD(day, 1, StartDate) <= @EndDate
)
select StartDate,
    case 
        when cast(@StartDate as date) = cast(@EndDate as date) then datediff(minute, @StartDate, @EndDate ) 
        when StartDate = cast(@StartDate as date) then datediff(minute, @StartDate, cast(EndDate as datetime)) 
        when StartDate = cast(@EndDate as date) then datediff(minute, cast(StartDate as datetime), @EndDate) 
        else 1440 end
from cte

答案 1 :(得分:1)

试试这样:

备注:如果完整的intervall可以超过10天,只需在计数表中添加更多值。注意:这个解决方案还没有涵盖这种情况,当开始和结束是在同一天......

DECLARE @d1 DATETIME={ts'2015-10-05 08:00:00'};
DECLARE @d2 DATETIME={ts'2015-10-07 12:00:00'};

WITH SomePreCalculations AS
(
    SELECT @d1 AS D1
          ,@d2 AS D2
          ,CAST(@d1 AS DATE) AS StartDate  
          ,DATEADD(DAY,1,CAST(@d1 AS DATE)) AS FirstMidnight
          ,CAST(@d2 AS DATE) AS LastMidnight  
)
,Differences AS
(
    SELECT *
          ,DATEDIFF(MINUTE,D1,FirstMidnight) AS TilMidnight
          ,DATEDIFF(MINUTE,LastMidnight,D2) AS FromMidnight
    FROM SomePreCalculations
)
,TallyTable AS
(
    SELECT RowInx FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS x(RowInx)
)
SELECT CAST(Date AS DATE),Minutes FROM
(
      SELECT 0 AS Inx, D1 AS Date, TilMidnight AS Minutes 
      FROM Differences  
UNION SELECT RowInx,(SELECT DATEADD(DAY,RowInx,(SELECT StartDate FROM SomePreCalculations))),1440
      FROM TallyTable   
      WHERE DATEADD(DAY,RowInx,(SELECT StartDate FROM SomePreCalculations))<(SELECT LastMidnight FROM SomePreCalculations)
UNION SELECT 99 AS Inx, D2, FromMidnight  
      FROM Differences  
) AS tbl
ORDER BY tbl.Inx