2014-09-08 3 views
0

다른 행에 겹치는 날짜가 포함될 데이터가 있습니다. 겹침이 들어있는 두 행마다 다음과 같이 적절하게 구분해야합니다. 모든기간을 겹치기 전, 겹치기 및 이후의 SQL에 외삽합니다.

첫째, 데이터는 다음과 같습니다 : 이것에 대한

EMPID FIRSTNAME SURNAME ACTIVITY START_DATE   END_DATE   HOURS_PER_DAY STATION 
101 ANDREW SMITH AVAILABLE 2013-07-08 09:00:00 2013-07-08 17:00:00 8.00    LONDON 
101 ANDREW SMITH SICKNESS 2013-07-08 07:00:00 2013-07-08 12:00:00 5.00    LONDON 

그 이유는 데이터가 원래 두 개의 테이블에서 와서 내가 하나에 두 테이블의 내용을 삽입 한 것입니다.

이 데이터는 결국 일인당 그룹화되어 총 '일일 시간'열을 제공합니다. 위의 표에서이 사람은 13 시간을 갖지만 위의 그림에서 볼 수 있듯이 두 기간의 기간은 겨우 10 시간입니다. 분류되어야 중첩

EMPID NAME ACTIVITY START_DATE   END_DATE   HOURS_PER_DAY STATION 
101 JOHN SICKNESS 2013-07-08 07:00:00 2013-07-08 09:00:00 2    LONDON 
101 JOHN SICKNESS 2013-07-08 09:00:00 2013-07-08 12:00:00 3    LONDON 
101 JOHN AVAILABLE 2013-07-08 12:00:00 2013-07-08 17:00:00 5    LONDON 

시간주기 동안 : 비트 오버랩은 오버랩 오버랩 후의 비트 전 - I의 결과를 3 행으로 분할 할 필요가 위의 예에서

병. 사용 가능 및 병 이외의 다른 옵션이 있지만 중복되는 유일한 것은 다른 유형의 병입니다. '병'과 '사용 가능'또는 '병'과 '훈련'의 충돌 사이의 충돌.

또한 데이터는 이미 24 시간으로 나뉘어져 있습니다. 즉, 4 일 동안 4 일간의 병목 기간을 이미 추정 했으므로 하루 열 시간이 24 시간을 초과하지 않습니다. 전체 24 시간 기간이있는 경우 종료일은 시작일 이후 정확히 1 일입니다. 시작일과 종료일 모두 자정에 있습니다. 필요한 것을 수행하려고 할 때 EMPID, NAME, CAST (START_DATE) AS DATE, CAST (END_DATE AS DATE) 및 STATION으로 데이터를 그룹화하려고했습니다. 이들은 비교해야 할 그룹핑을 결정하는 적절한 필드입니다.

주의 사항 : 제공된 것과 유사한 2500 행의 데이터와 다음 유형의 중복이 가능합니다 (AVAILABLE 항목이 09:00에 시작되고 17:00에 끝나면 - 예를 들어 그 정보를 사용하고있는 것은 아닙니다. :

  • 질병과 정확히 같은 시간에 시작과 끝 AVAILABLE - 예를 들어 질병은 09:00 시작 17:00 (결과 8시간 병)에서 끝이
  • 병이 가능한 항목 전에 시작 (예 : SICKNESS 2 시간, SICKNESS 3 시간, 5 시간 사용 가능)
  • SICKNESS는 AVAILABLE 중간에 시작됩니다. (예 : 병은 07:00에 시작하여 12:00에 끝납니다. AVAILABL 이후 엔트리와 엔트리 E 항목 (예 : 질병은 12:00에 시작하여 22:00에 끝납니다 (결과 : 3 시간 사용 가능, 5 시간 동안 겹침, 5 시간 동안 사용 가능).
  • SICKNESS는 AVAILABLE 입력 중에 시작하고 AVAILABLE 입력 중에 종료합니다. 병은 11:00에 시작하여 14:00에 끝납니다 (결과 : 2 시간 AVAILABLE, 3 시간 SICKNESS 중첩).
  • SICKNESS는 AVAILABLE 항목보다 먼저 시작되고 AVAILABLE 항목 다음에 끝납니다. 병은 06:00에 시작하여 18:00에 끝납니다 (결과 : 12 시간 병력).
  • 질병은 AVAILABLE 항목의 중간에서 시작하여 동시에 끝납니다.
  • 병은 AVAILABLE 항목의 중간에서 시작하여 AVAILABLE 항목.

'AVAILABLE'이 유일한 옵션은 아닙니다.

임시 테이블 @INDIVIDUALDAYS에 저장되어있는이 게시물의 맨 위에있는 형식으로 데이터가 반환되는 시점까지 쿼리가 진행 중입니다. @INDIVIDUALDAYS에 위에 설명하십시오.

나는 데이터가 같은 열 (나는 거기에 몇 가지 더 조작 및 계산을 할 필요가처럼 여러 행에 추정.

를 내가 제공 할 행복 해요와 정확히 같은 형식으로 반환 받으려는 내 ,

101 Andrew Smith Available 2014-08-19 09:00:00.000 2014-08-19 17:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-19 09:00:00.000 2014-08-19 17:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-20 12:00:00.000 2014-08-20 19:00:00.000 7.00 London 
101 Andrew Smith Available 2014-08-20 09:00:00.000 2014-08-20 17:00:00.000 8.00 London 
101 Andrew Smith Available 2014-08-21 09:00:00.000 2014-08-21 17:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-21 04:00:00.000 2014-08-21 12:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-22 06:00:00.000 2014-08-22 18:00:00.000 12.00 London 
101 Andrew Smith Available 2014-08-22 09:00:00.000 2014-08-22 17:00:00.000 8.00 London 
101 Andrew Smith Available 2014-08-23 09:00:00.000 2014-08-23 17:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-23 11:00:00.000 2014-08-23 14:00:00.000 3.00 London 
101 Andrew Smith Available 2014-08-24 09:00:00.000 2014-08-23 17:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-24 09:00:00.000 2014-08-23 14:00:00.000 3.00 London 
101 Andrew Smith Available 2014-08-25 09:00:00.000 2014-08-23 17:00:00.000 8.00 London 
101 Andrew Smith SICKNESS 2014-08-25 11:00:00.000 2014-08-23 17:00:00.000 3.00 London 
+0

위의 옵션 3을 사용하지 않아야합니다. SICKNESS는 AVAILABLE 항목의 중간에서 시작하여 AVAILABLE 항목 다음에 끝납니다. 병은 12:00에 시작하여 22:00에 끝납니다 (결과 : 3 시간 사용 가능, 중복시 5 시간, 5 시간 시력). 그들이 아플 경우 아프지 않습니까? – LeeG

답변

0

이 작업을 수행하려면 : 현재 코드가 필요하지만, 200 선 길이와 내가 당신에게 충분한 정보

다음은 위의 7 가지 permeations 커버 일부 샘플 데이터가

을 준 믿는다면 먼저 두 가지를 모두 얻어야합니다. ows는 1 행으로 결합됩니다. 모든 데이터를 단일 행으로 가져온 다음 일련의 유니온 쿼리를 사용하여 각 조건에 대해 하나씩 결과 행을 작성할 수 있습니다.

이것은 테스트 데이터 구축 :

INSERT INTO TData 
    ([ID], [FName], [LName], [Status], [StartTime], [EndTime], [Hours], [Location]) 
VALUES 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-19 09:00:00', '2014-08-19 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-19 09:00:00', '2014-08-19 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-20 12:00:00', '2014-08-20 19:00:00', 7.00, 'London'), 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-20 09:00:00', '2014-08-20 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-21 09:00:00', '2014-08-21 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-21 04:00:00', '2014-08-21 12:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-22 06:00:00', '2014-08-22 18:00:00', 12.00, 'London'), 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-22 09:00:00', '2014-08-22 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-23 09:00:00', '2014-08-23 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-23 11:00:00', '2014-08-23 14:00:00', 3.00, 'London'), 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-24 09:00:00', '2014-08-23 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-24 09:00:00', '2014-08-23 14:00:00', 3.00, 'London'), 
    (101, 'Andrew', 'Smith', 'Available', '2014-08-25 09:00:00', '2014-08-23 17:00:00', 8.00, 'London'), 
    (101, 'Andrew', 'Smith', 'SICKNESS', '2014-08-25 11:00:00', '2014-08-23 17:00:00', 3.00, 'London') 
; 

을 그리고 여기 결과의 시작이다. 마지막으로 표시 될 각 행/조건에 대해 UNION 절을 더 추가해야합니다.

;WITH Combined AS (
SELECT T1.*, t2.StartTime AS S_StartTime, t2.EndTime AS S_EndTime, 
     t2.Status AS S_Status, t2.Hours AS S_Hours 
FROM TData T1 --Change TData to your table name 
LEFT OUTER JOIN Tdata T2 ON T1.id = T2.id 
     AND CAST(T1.StartTime AS date) = CAST(T2.StartTime as date) 
     AND t1.Status <> t2.Status 
WHERE T1.Status <> 'SICKNESS' 
) 
--this is case 1 Show sickness only? If not, add another row 
SELECT ID, FName, LName, s_Status AS Status, 
     s_StartTime AS StartTime, s_EndTime AS EndTime, 
     S_Hours AS Hours, Location 
FROM combined 
WHERE StartTime = S_StartTime and EndTime = s_EndTime 
UNION --Case 2 Row 1 
SELECT ID, FName, LName, s_Status AS Status, 
     s_StartTime AS StartTime, StartTime AS EndTime, 
     DATEDIFF(minute,S_StartTime,StartTime)/60 AS Hours, Location 
FROM combined 
WHERE S_StartTime < StartTime 
     AND S_EndTime BETWEEN StartTime AND EndTime 
UNION --case 2 row 2 
SELECT ID, FName, LName, S_Status AS Status, 
     StartTime AS StartTime, S_EndTime AS EndTime, 
     DATEDIFF(minute,StartTime,S_EndTime)/60 AS Hours, Location 
FROM combined 
WHERE S_StartTime < StartTime 
     AND S_EndTime BETWEEN StartTime AND EndTime 
UNION --case 2 row 3 
SELECT ID, FName, LName, Status, 
     S_EndTime AS StartTime, EndTime AS EndTime, 
     DATEDIFF(minute,S_EndTime,EndTime)/60 AS Hours, Location 
FROM combined 
WHERE S_StartTime < StartTime 
     AND S_EndTime BETWEEN StartTime AND EndTime 

나는 나머지 절을 다룰 수는 있지만 어떻게해야하는지 분명히해야한다. 추가 도움이 필요하면 알려주세요.