На этом рисунке показано то, что я пытался выполнить в MSSQL.
Это расписание с несколькими временными диапазонами, от A до Bэто сверхурочное время, обычная работа B - C утром, обеденное время C – D, обычная работа D – E днем и E – F, сверхурочное время.
Ради простоты я объявилвручную A, B, C, D, E и F до фиксированных значений.В действительности они будут подаваться из другой таблицы, но это не относится к данной проблеме.
Вертикальные стрелки представляют время включения / выключения тактирования.
Итак, скажем, в 8 утра иOUT это 7 вечера. * 10101
Как я могу получить следующее?
Работа: 8 ч
Обед: 1 ч
Сверхурочные: 2 ч
Без использования путаницы IF и зная, что IN может быть в середине B иНапример, C.
У кого-то, работающего в 11 утра и заканчивающего в 7 вечера, теперь будет работа = 6 часов, обед = 1 час, сверхурочные = 1 час.
Спасибо.
Как пример, мой текущий код спагетти, конечно, есть более элегантный (и более чистый) способ достигнуть этого.
declare @clockIn time = '08:00'
declare @clockOut time = '19:00'
declare @a time= '00:00'
...all possible limits defined here...
declare @f time= '23:59'
tests using C to D only:
-- in block
IF(@clockIn >= @c
AND @clockOut <= @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @clockIn, @clockOut));
END;
-- outside block
IF(@clockIn < @c
AND @clockOut > @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @c, @d));
END;
-- cIn in block, cOut outside
IF(@clockIn >= @c
AND @clockOut > @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @clockIn, @d));
END;
-- cIn outside, cIn inside
IF(@clockIn < @c
AND @clockOut <= @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @c, @clockOut));
END
select @ax as overtime,@at as work,@ai as lunch