2010-03-16 3 views
2

나는 Shift가 종업원이 StartTime과 EndTime에서 수행 한 작업을 계산하는 함수를 얻으려고 노력해 왔습니다. 여기에 제가 지금까지 가지고있는 코드가 있는데, 잘못 계산 된 것 같습니다.StartTime과 EndTime에서 Shift를 계산하는 SQL 함수

Shift 1 from 08:00:00 - 16:30:00 
Shift 2 from 16:00:00 - 00:30:00 
Shift 3 from 00:00:00 - 08:30:00 

또한 시프트 사이의 시간이 가장 많은 시프트가 나타납니다.

감사합니다, G는 집합 기반 문제에 대한 반복적 인 접근을하려는 것처럼 느낀다


`FUNCTION [dbo].[ShiftDifferential] (
@StartTime time(0), 
@EndTime time(0) 
) 
RETURNS int 
AS 
BEGIN 
--DECLARE @StartTime time(0) 
--DECLARE @EndTime time(0) 

-- Declare the return variable here 
DECLARE @Shift1StartTime time(0) 
DECLARE @Shift2StartTime time(0) 
DECLARE @Shift3StartTime time(0) 
DECLARE @Shift1EndTime time(0) 
DECLARE @Shift2EndTime time(0) 
DECLARE @Shift3EndTime time(0) 

DECLARE @HrsShift1 decimal(18,2) 
DECLARE @HrsShift2 decimal(18,2) 
DECLARE @HrsShift3 decimal(18,2) 

DECLARE @ShiftDiff int 

--SET @StartTime = '09:00:00' 
--SET @EndTime = '13:00:00' 

SET @Shift1StartTime = '08:00:00' 
SET @Shift2StartTime = '16:00:00' 
SET @Shift3StartTime = '00:00:00' 
SET @Shift1EndTime = '16:30:00' 
SET @Shift2EndTime = '00:30:00' 
SET @Shift3EndTime = '08:30:00' 



--SELECT DATEDIFF(HH, @Shift1StartTime, @EndTime) 

-- hours are between shift 3 and shift 1 
if DATEDIFF(HH, @Shift1StartTime, @StartTime) < 0 AND (DATEDIFF(hh, @Shift1StartTime, @EndTime) < 8.0 AND DATEDIFF(hh, @Shift1StartTime, @EndTime) > 0) 
    begin 
    --PRINT 'Shift 3-1 step1' 
    SET @HrsShift3 = DATEDIFF(HH, @StartTime, @Shift1StartTime) 
    SET @HrsShift1 = DATEDIFF(HH, @Shift1StartTime, @Endtime) 
    --PRINT @HrsShift3 
    --PRINT @HrsShift1 

    -- get shift with most hours 
    if @HrsShift3 > @HrsShift1 
    begin 
    SET @ShiftDiff = 3 
    end 
    else 
    begin 
    SET @ShiftDiff = 1 
    end 
    end 

-- hours are in shift 1 
if (DATEDIFF(HH, @Shift1StartTime, @StartTime) = 0 AND DATEDIFF(HH, @Shift1StartTime, @EndTime) <= 8) 
    OR (DATEDIFF(HH, @Shift1StartTime, @StartTime) > 0 AND DATEDIFF(HH, @Shift1StartTime, @EndTime) <= 8) 
    begin 
    --PRINT 'Shift 1 step2' 
    SET @HrsShift3 = 0 
    SET @HrsShift1 = DATEDIFF(HH, @StartTime, @EndTime) 
    --PRINT @HrsShift3 
    --PRINT @HrsShift1 

    -- only one shift with hours 
    SET @ShiftDiff = 1 
    end 

-- hours are between shift 1 and shift 2 
if DATEDIFF(HH, @Shift2StartTime, @StartTime) < 0 and (DATEDIFF(HH, @Shift2StartTime, @EndTime) < 8.0 AND DATEDIFF(HH, @Shift2StartTime, @EndTime) > 0) 
    begin 
    --PRINT 'Shift 1-2 step1' 
    SET @HrsShift1 = DATEDIFF(HH, @StartTime, @Shift2StartTime) 
    SET @HrsShift2 = DATEDIFF(HH, @Shift2StartTime, @Endtime) 
    --PRINT @HrsShift1 
    --PRINT @HrsShift2 

    -- get the shift with most hours 
    if @HrsShift1 > @HrsShift2 
    begin 
    SET @ShiftDiff = 1 
    end 
    else 
    begin 
    SET @ShiftDiff = 2 
    end 
    end 

-- hours are in shift 2 
if (DATEDIFF(HH, @Shift2StartTime, @StartTime) = 0 AND DATEDIFF(HH, @Shift2StartTime, @EndTime) <= 8) 
    OR (DATEDIFF(HH, @Shift2StartTime, @StartTime) > 0 AND DATEDIFF(HH, @Shift2StartTime, @EndTime) <= 8) 
    begin 
    --PRINT 'Shift 2 step2' 
    SET @HrsShift3 = 0 
    SET @HrsShift1 = DATEDIFF(HH, @StartTime, @EndTime) 
    --PRINT @HrsShift3 
    --PRINT @HrsShift1 

    -- only one shift with hours 
    SET @ShiftDiff = 2 
    end 

-- hours are between shift 2 and shift 3 - overnight shift 
if DATEDIFF(HH, @StartTime, @EndTime) < 0 
    begin 
    --PRINT 'Shift 2-3 step1' 
    SET @HrsShift2 = DATEDIFF(HH, @StartTime, '23:59:59') + DATEDIFF(HH, '00:00:00', '00:30:00') 
    SET @HrsShift3 = DATEDIFF(HH, '00:30:00', @EndTime) 
    --PRINT @HrsShift2 
    --PRINT @HrsShift3 

    -- get the shift with most hours 
    if @HrsShift2 > @HrsShift3 
    begin 
    SET @ShiftDiff = 2 
    end 
    else 
    begin 
    SET @ShiftDiff = 3 
    end 
    end 

-- hours are in shift 3 
if (DATEDIFF(HH, @Shift3StartTime, @StartTime) = 0 AND DATEDIFF(HH, @Shift3StartTime, @EndTime) <= 8) 
    OR (DATEDIFF(HH, @Shift3StartTime, @StartTime) > 0 AND DATEDIFF(HH, @Shift3StartTime, @EndTime) <= 8) 
    begin 
    --PRINT 'Shift 3 step2' 
    SET @HrsShift2 = 0 
    SET @HrsShift3 = DATEDIFF(HH, @StartTime, @EndTime) 
    --PRINT @HrsShift2 
    --PRINT @HrsShift3 

    -- only one shift with hours 
    SET @ShiftDiff = 3 
    end 

RETURN @ShiftDiff; 
END` 
+2

귀하의 질문은 무엇입니까? –

답변

1

.

작업 표 항목에 입력 한 시간과 가장 겹치는 교대를 찾으려고하는 것처럼 들리 네요.

이 작업을 통해 원하는대로 시간대 표를 사용할 수 있으므로 설정이 쉽고 쉽게 확장 할 수 있습니다. 이것은 time 유형을 사용하여 일을 시작한다고 가정하지만, 그 다음날에 교대가 끝나기 때문에 datetime으로 캐스팅합니다.

with 
Shifts as 
(
SELECT ShiftID, cast(StartTime as datetime) as StartTime, 
    case 
     when EndTime < StartTime 
     then dateadd(day,1,cast(EndTime as datetime)) 
     else cast(EndTime as datetime) 
    end as EndTime 
FROM Shifts 
), 
Times as 
(select 1 as TimeID, 
    cast(@StartTime as datetime) as StartTime, 
    case 
     when @EndTime < @StartTime 
     then dateadd(day,1,cast(@EndTime as datetime)) 
     else cast(@EndTime as datetime) 
    end as EndTime 
), 
Overlaps as 
(
select s.ShiftID, t.TimeID, 
     case when s.StartTime > t.StartTime then s.StartTime else t.StartTime end as StartOverlap, 
     case when s.EndTime < t.EndTime then s.EndTime else t.EndTime end as EndOverlap, 
from Shifts s 
cross join Times t 
), 
OrderedOverlaps as 
(
select *, row_number() over(partition by TimeID order by datediff(min,StartOverlap,EndOverlap) desc) as RowNum 
from Overlaps 
) 
select s.ShiftID, t.TimeID 
from OrderedOverlaps 
where RowNum = 1; 
+0

안녕하세요 Rob 빠른 답장을 보내 주셔서 감사합니다. 몇 가지 사례를 테스트했으며 코드가 훌륭하게 보입니다. 그러나 야간 근무와 같은 문제가 있습니다. 대부분의 근무 시간이 쉬프트 3에 있기 때문에 쉬프트 3이 주어져야합니다. SET @StartTime = '22 : 00 : 00 ' SET @ EndTime = '03 : 30 : 00 또한'FROM Shifts '는 ShiftID와 StartTime/EndTime 정보를 담고있는 테이블인가요? datediff (min, StartOverlap, EndOverlap) 당신은 datediff (mi, StartOverlap, EndOverlap)를 의미합니까? G – Gentis

+0

아, 네. 나는 실제로 분을 의미했습니다. 그리고 당신 말이 맞아, 아마도 "다음날 이동"을 넣는 코드가 있어야합니다. 조합 : 모두 SELECT ShiftID, dateadd (day, 1, cast (StartTime as datetime)) StartTime, dateadd (day, 1 , 경우 EndTime

+0

좋은 접근 방식. 훌륭하게 작동합니다. 다시 한번 감사드립니다. G – Gentis