Разбиение времени + длительности на интервалы в т-квл - PullRequest
1 голос
/ 31 октября 2008

Кто-нибудь знает простой метод решения этой проблемы?

У меня есть таблица, которая состоит из времени начала событий и связанных с ними длительностей. Я должен быть в состоянии разделить продолжительность события на тридцать минут. Так, например, если событие начинается в 10:45:00, а продолжительность - 00:17:00, то возвращаемый набор должен выделить 15 минут с интервалом 10:30:00 и 00:02:00 минут до 11:00. : 00 интервал.

Я уверен, что могу придумать неуклюжий подход, но хотел бы что-нибудь попроще. Я думаю, это случается довольно часто, но сегодня Google бесполезен.

Спасибо

Steve

Ответы [ 2 ]

3 голосов
/ 31 октября 2008

Вы можете создать таблицу поиска только с временем (более 24 часов) и присоединиться к этой таблице. Вам нужно будет переназначить дату на ту, что использовалась в поиске. Затем выполните датировку верхнего и нижнего интервалов, чтобы определить их длительность. Каждый средний интервал будет 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
2 голосов
/ 31 октября 2008

Создать TVF, который разделяет одно событие:

ALTER FUNCTION dbo.TVF_TimeRange_Split_To_Grid
(
    @eventStartTime datetime
    , @eventDurationMins float
    , @intervalMins int
)
RETURNS @retTable table
(
    intervalStartTime datetime
    ,intervalEndTime datetime
    ,eventDurationInIntervalMins float
)
AS
BEGIN

    declare @eventMinuteOfDay int
    set @eventMinuteOfDay = datepart(hour,@eventStartTime)*60+datepart(minute,@eventStartTime)

    declare @intervalStartMinute int
    set @intervalStartMinute = @eventMinuteOfDay - @eventMinuteOfDay % @intervalMins

    declare @intervalStartTime datetime
    set @intervalStartTime = dateadd(minute,@intervalStartMinute,cast(floor(cast(@eventStartTime as float)) as datetime))

    declare @intervalEndTime datetime
    set @intervalEndTime = dateadd(minute,@intervalMins,@intervalStartTime)

    declare @eventDurationInIntervalMins float

    while (@eventDurationMins>0)
    begin

        set @eventDurationInIntervalMins = cast(@intervalEndTime-@eventStartTime as float)*24*60
        if @eventDurationMins<@eventDurationInIntervalMins 
            set @eventDurationInIntervalMins = @eventDurationMins

        insert into @retTable
        select @intervalStartTime,@intervalEndTime,@eventDurationInIntervalMins

        set @eventDurationMins = @eventDurationMins - @eventDurationInIntervalMins
        set @eventStartTime = @intervalEndTime

        set @intervalStartTime = @intervalEndTime
        set @intervalEndTime = dateadd(minute,@intervalMins,@intervalEndTime)
    end

    RETURN 
END
GO

Тест:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...