Tsql 分割时间+;t-sql中的时间间隔

Tsql 分割时间+;t-sql中的时间间隔,tsql,datetime,Tsql,Datetime,有人知道解决这个问题的简单方法吗 我有一个表,其中包括事件的开始时间和相关的持续时间。我需要能够将事件持续时间划分为30分钟的间隔。因此,例如,如果事件在10:45:00开始,持续时间为00:17:00,则返回的集合应为10:30:00间隔分配15分钟,为11:00:00间隔分配00:02:00分钟 我相信我能想出一个笨拙的方法,但我想简单一点。我想这肯定是经常出现的,但谷歌今天却无济于事 谢谢 Steve您可以创建一个只包含时间(超过24小时)的查找表,并加入该表。您需要将日期重设为查找中使用

有人知道解决这个问题的简单方法吗

我有一个表,其中包括事件的开始时间和相关的持续时间。我需要能够将事件持续时间划分为30分钟的间隔。因此,例如,如果事件在10:45:00开始,持续时间为00:17:00,则返回的集合应为10:30:00间隔分配15分钟,为11:00:00间隔分配00:02:00分钟

我相信我能想出一个笨拙的方法,但我想简单一点。我想这肯定是经常出现的,但谷歌今天却无济于事

谢谢


Steve

您可以创建一个只包含时间(超过24小时)的查找表,并加入该表。您需要将日期重设为查找中使用的日期。然后对上下间隔执行datediff,计算出它们的持续时间。每次中间休息时间为30分钟

create table #interval_lookup (
  from_date datetime,
  to_date datetime
)

declare @time datetime
set @time = '00:00:00'

while @time < '2 Jan 1900'
  begin
    insert into #interval_lookup values (@time, dateadd(minute, 30, @time))
    set @time = dateadd(minute, 30, @time)
  end

declare @search_from datetime
declare @search_to datetime

set @search_from = '10:45:00'
set @search_to = dateadd(minute, 17, @search_from) 

select
  from_date as interval,
  case
    when from_date <= @search_from and 
         @search_from < to_date and 
         from_date <= @search_to and 
         @search_to < to_date 
         then datediff(minute, @search_from, @search_to)
    when from_date <= @search_from and 
         @search_from < to_date 
         then datediff(minute, @search_from, to_date)
    when from_date <= @search_to and 
         @search_to < to_date then 
         datediff(minute, from_date, @search_to)
    else 30
  end as duration
from
  #interval_lookup
where
  to_date > @search_from
  and from_date <= @search_to
create table#interval#u查找(
从日期时间开始,
截止日期时间
)
声明@time-datetime
设置@time='00:00:00'
而@time<'1900年1月2日'
开始
插入#间隔_查找值(@time,dateadd(分钟,30,@time))
设置@time=dateadd(分钟,30,@time)
结束
声明@search\u from datetime
将@search\u声明为datetime
设置@search\u from='10:45:00'
将@search\u设置为=dateadd(分钟,17,@search\u开始)
选择
从_日期作为间隔,
案例

当from_date时,您可以创建一个只包含时间(超过24小时)的查找表,并加入该表。您需要将日期重设为查找中使用的日期。然后对上下间隔执行datediff,计算出它们的持续时间。每次中间休息时间为30分钟

create table #interval_lookup (
  from_date datetime,
  to_date datetime
)

declare @time datetime
set @time = '00:00:00'

while @time < '2 Jan 1900'
  begin
    insert into #interval_lookup values (@time, dateadd(minute, 30, @time))
    set @time = dateadd(minute, 30, @time)
  end

declare @search_from datetime
declare @search_to datetime

set @search_from = '10:45:00'
set @search_to = dateadd(minute, 17, @search_from) 

select
  from_date as interval,
  case
    when from_date <= @search_from and 
         @search_from < to_date and 
         from_date <= @search_to and 
         @search_to < to_date 
         then datediff(minute, @search_from, @search_to)
    when from_date <= @search_from and 
         @search_from < to_date 
         then datediff(minute, @search_from, to_date)
    when from_date <= @search_to and 
         @search_to < to_date then 
         datediff(minute, from_date, @search_to)
    else 30
  end as duration
from
  #interval_lookup
where
  to_date > @search_from
  and from_date <= @search_to
create table#interval#u查找(
从日期时间开始,
截止日期时间
)
声明@time-datetime
设置@time='00:00:00'
而@time<'1900年1月2日'
开始
插入#间隔_查找值(@time,dateadd(分钟,30,@time))
设置@time=dateadd(分钟,30,@time)
结束
声明@search\u from datetime
将@search\u声明为datetime
设置@search\u from='10:45:00'
将@search\u设置为=dateadd(分钟,17,@search\u开始)
选择
从_日期作为间隔,
案例
从开始日期创建拆分单个事件的TVF时:
测试结果:
示例用法:
样本使用结果:
创建拆分单个事件的TVF:
测试结果:
示例用法:
样本使用结果:

我很喜欢这种方法,让我的看起来有点难看。我想知道性能差异是什么样的?我只是需要编辑我的灵魂,所以它看起来也有点难看;)。我以前误读了问题要求。我相信您的解决方案会执行得更快。但是,我的解决方案在间隔长度方面是动态的;)我很喜欢这种方法,让我的看起来有点难看。我想知道性能差异是什么样的?我只是需要编辑我的灵魂,所以它看起来也有点难看;)。我以前误读了问题要求。我相信您的解决方案会执行得更快。但是,我的解决方案在间隔长度方面是动态的;)
select getdate()
select * from dbo.TVF_TimeRange_Split_To_Grid(getdate(),23,30)
2008-10-31 11:28:12.377

intervalStartTime       intervalEndTime         eventDurationInIntervalMins
----------------------- ----------------------- ---------------------------
2008-10-31 11:00:00.000 2008-10-31 11:30:00.000 1,79372222222222
2008-10-31 11:30:00.000 2008-10-31 12:00:00.000 21,2062777777778
select input.eventName, result.* from
(
    select 
        'first' as eventName
        ,cast('2008-10-03 10:45' as datetime) as startTime
        ,17 as durationMins
    union all
    select 
        'second' as eventName
        ,cast('2008-10-05 11:00' as datetime) as startTime
        ,17 as durationMins
    union all
    select 
        'third' as eventName
        ,cast('2008-10-05 12:00' as datetime) as startTime
        ,100 as durationMins
) input
cross apply dbo.TVF_TimeRange_Split_To_Grid(input.startTime,input.durationMins,30) result
eventName intervalStartTime       intervalEndTime         eventDurationInIntervalMins
--------- ----------------------- ----------------------- ---------------------------
first     2008-10-03 10:30:00.000 2008-10-03 11:00:00.000 15
first     2008-10-03 11:00:00.000 2008-10-03 11:30:00.000 2
second    2008-10-05 11:00:00.000 2008-10-05 11:30:00.000 17
third     2008-10-05 12:00:00.000 2008-10-05 12:30:00.000 30
third     2008-10-05 12:30:00.000 2008-10-05 13:00:00.000 30
third     2008-10-05 13:00:00.000 2008-10-05 13:30:00.000 30
third     2008-10-05 13:30:00.000 2008-10-05 14:00:00.000 10

(7 row(s) affected)