2012-01-18 2 views
0

Учитывая начальное и конечное время, я хочу знать, сколько минут за определенный час покрыто.Рассчитать, сколько минут было использовано в заданный час

create function CalcMinsInHour(@start datetime, @end datetime, @hour int) 
returns int 
as 
begin 
    --Looking for best way to write this part 
end 

CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 7) should return 0 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 8) should return 45 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 9) should return 60 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 10) should return 30 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 11) should return 0 

Редактировать: @Start и @End представляют временные часы для часов сотрудников. Так что да, они могут охватывать два дня, когда они работают за полночь, но не более того.

+2

являются диапазоны дат гарантировано только в тот же день? – RQDQ

+1

Лучший способ? Звучит скорее как «способ». :) – bzlm

+1

Как вы хотите обрабатывать несколько интервалов времени? Если вы введете '2012-01-18 8: 15' и' 2012-01-20-13: 30', что бы вы хотели получить? – JNK

ответ

3

Это должно сделать трюк:

ALTER FUNCTION dbo.CalcMinsInHour(@start DATETIME, @end DATETIME, @hour INTEGER) 
RETURNS INTEGER 
AS 
BEGIN 
    DECLARE @StartOfHour DATETIME 
    DECLARE @EndOfHour DATETIME 
    SELECT @StartOfHour = DATEADD(hh, @hour, CAST(CAST(@start AS DATE) AS DATETIME)) 
    IF NOT (@StartOfHour BETWEEN @start and @end) 
     SET @StartOfHour = DATEADD(hh, @hour, CAST(CAST(@end AS DATE) AS DATETIME)) 

    SELECT @EndOfHour = DATEADD(hh, 1, @StartOfHour) 

RETURN 
(
SELECT 
    CASE WHEN @EndOfHour < @start OR @StartOfHour > @end THEN 0 ELSE 
     DATEDIFF(mi, 
      CASE WHEN @StartOfHour <= @start THEN @start ELSE @StartOfHour END, 
      CASE WHEN @EndOfHour > @end THEN @end ELSE @EndOfHour END) 
    END 
) 
END 
+0

+1 - намного более элегантный, чем мое заявление о заявлении «CASE». Я еще не закончил :) – JNK

+0

это не работает, если интервал «2012-01-18 20:15» - «2012-01-19 2:30», а час 2, например – GolfWolf

+0

Удивительный, вы рок. Я куплю ваш обед, если вы когда-нибудь в Далласе :) –

1

Можете ли вы использовать DateDiff?

select DATEDIFF(Minute, '2011-11-10 00:00:59.900', '2011-11-10 00:01:00.100')

+0

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

1

Вот функция, которая вычисляет общее количество минут (также работает с несколькими дней):

create function CalcMinsInHour(@start datetime, @end datetime, @hour int) 
    returns int 
as 
begin 

    declare @selecterHourIntervals table (HourStart datetime, HourEnd datetime) 
    declare @currentDate datetime 

    /* start in the @start date, but the hour we want to count */ 
    set @currentDate = dateadd(hour, @hour, convert(datetime, convert(date, @start))) 

    /* for every day between @[email protected] add out hour interval */ 
    while @currentDate <= @end 
    begin 
     insert into @selecterHourIntervals values (
         @currentDate, 
         dateadd(hour, 1, @currentDate)) 

     set @currentDate = dateadd(day, 1, @currentDate) 
    end 

    declare @totalMinutes int 

    /* for every hour interval in the table, select number of minutes 
     trimmed by the @start - @end interval and sum */ 
    select @totalMinutes = sum(DailyMinutes) 
    from 
     (select 
      datediff(minute, 
      case when HourStart > @start then HourStart else @start end, 
      case when HourEnd < @end then HourEnd else @end end) as DailyMinutes 
     from @selecterHourIntervals) TrimmedIntervals 
    where DailyMinutes > 0 

    return isnull(@totalMinutes, 0) 

end 
+0

+1 для усилий :) –

+0

То есть, я понимаю, что этот ответ может быть более «правильным», чем AdaTheDev, но я действительно хотел решение без циклов, временных таблиц и т. Д., Что бы замедлить его ... но определенно нужно дайте вам +1 за усилия! –

+0

@BrandonMoore - Я знаю, решение AdaTheDev действительно намного более изящно и может быть слегка скорректировано, чтобы дать правильный результат. – GolfWolf

Смежные вопросы