繁体   English   中英

如何在SQL中将日期范围连续地分成一天中每一小时花费的时间

[英]How to split a date range in a row into time spent in each hour in a day in SQL

我有如下数据,带有开始和结束日期。 记录将仅在同一天开始和结束。

我想将每个记录扩展为具有小时列,其中包含每小时花费的时间。 例如:

ID      START_TIME        END_TIME           
AAAA    09/10/2015 9:30   09/10/2015 13:15

会成为

ID      START_TIME      END_TIME        H1  H2  H3  H4  H5  H6  H7  H8  H9  H10 H11 H12 H13 H14 H15 H16 H17 H18 H19 H20 H21 H22 H23 H24

AAAA    9/10/2015 9:30  9/10/2015 13:15 0   0   0   0   0   0   0   0   0   30  60  60  60  15  0   0   0   0   0   0   0   0   0   0

您可以通过创建一个小时数为24的表来实现此目的,该表具有小时数,小时数和开始和结束时间,将其与数据交叉联接,使用额外的表进行计算,并使用数据透视将数据重新组合在一起。

这对于处理一天的结束有一点丑陋的技巧,因此从结束时间中减去一秒钟。

SQL:

with data as (
  select *,
  case when convert(time, endtime) < S or convert(time, starttime) > E
  then 0 else 
    60
    - case when S < convert(time, starttime) and E > convert(time, starttime)
      then datediff(minute, convert(time, starttime), E) else 0 end
    - case when S < convert(time, endtime) and E >= convert(time, endtime)
      then datediff(second, dateadd(second, -1, convert(time, endtime)), E) / 60 else 0 end
  end as minutes
  from table1 d cross join hours h
)

select * from 
(SELECT id, starttime, endtime, h, minutes from data) p
PIVOT
(
sum (minutes)
FOR H IN
([0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23])
) AS pvt

我使用的设置:

create table table1 (
  id char(4),
  starttime datetime,
  endtime datetime
)

insert into table1 values 
('AAAA','09/10/2015 9:30','09/10/2015 13:15'),
('BBBB','09/10/2015 9:30','09/10/2015 23:59')

create table hours (
  H tinyint,
  S time,
  E time
)

insert into hours values 
(0,'00:00','01:00'),
(1,'01:00','02:00'),
(2,'02:00','03:00'),
(3,'03:00','04:00'),
(4,'04:00','05:00'),
(5,'05:00','06:00'),
(6,'06:00','07:00'),
(7,'07:00','08:00'),
(8,'08:00','09:00'),
(9,'09:00','10:00'),
(10,'10:00','11:00'),
(11,'11:00','12:00'),
(12,'12:00','13:00'),
(13,'13:00','14:00'),
(14,'14:00','15:00'),
(15,'15:00','16:00'),
(16,'16:00','17:00'),
(17,'17:00','18:00'),
(18,'18:00','19:00'),
(19,'19:00','20:00'),
(20,'20:00','21:00'),
(21,'21:00','22:00'),
(22,'22:00','23:00'),
(23,'23:00','23:59:59')

SQL Fiddle中的相同示例

您可以使用大量的case说明来做到这一点。 每小时小时数的逻辑基于时间跨度是否在小时之前,期间或之后开始,以及时间结束之前,期间或之后开始:

select id, start_time, end_time,
       ((case when datepart(hour, end_time) < 0 then 0
              when datepart(hour, end_time) = 0 then datepart(minute, end_time)
              else 60
         end)
        (case when datepart(hour, start_time) < 0 then 60
              when datepart(hour, start_time) = 0 then datepart(minute, start_time)
              else 0
         end)
       ) as h00,
       ((case when datepart(hour, end_time) < 1 then 0
              when datepart(hour, end_time) = 1 then datepart(minute, end_time)
              else 60
         end)
        (case when datepart(hour, start_time) < 1 then 60
              when datepart(hour, start_time) = 1 then datepart(minute, start_time)
              else 0
         end)
       ) as h01,
       . . .

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM