2014-06-19 3 views
1

다음 데이터로 구성된 테이블이 있습니다.SQL - 홀수/짝수 열의 다른 열로의 차이점

Employee  TimeRegister1   TimeRegister2   TimeRegister3   TimeRegister4   
    77 2014-04-01 11:51:43.000 2014-04-01 14:03:52.000 2014-04-01 14:17:01.000 2014-04-01 16:01:12.000 
    77 2014-04-03 09:48:33.000 2014-04-03 12:13:43.000 2014-04-03 12:22:27.000 2014-04-03 14:03:43.000 
    181 2014-04-02 08:24:34.000 2014-04-02 13:01:10.000 2014-04-02 14:30:31.000 2014-04-02 18:04:04.000 

무엇 I 필요하면 다른 컬럼에 작성하고, 각 종업원/하루의 각 열 쌍 (홀수 마이너스) 사이의 차이로부터 계산 된 총.

위 예의 경우 Employee 77 and 2014-04-01의 경우 TimeRegister 2 - TimeRegister 1, TimeRegister 4 - TimeRegister 3 사이의 차이점의 합계를 다른 열에 써야합니다. 이 같은

뭔가 할 수 있어야 출력 (초, 관련성이없는 단지 시간/분 필요) 다음 TimeRegister 열 게다가

Employee  TimeRegister1   TimeRegister2   TimeRegister3   TimeRegister4    CALCULATEDCOL   
    77  2014-04-01 11:51:43.000 2014-04-01 14:03:52.000 2014-04-01 14:17:01.000 2014-04-01 16:01:12.000 2014-04-01 03:56:00.000 

최대 30가 (난 그냥 4 열을 보였으 나 더 수) 일 수있다 그래서 열이 다 떨어질 때까지 각각의 홀수/짝수 쌍에 대한 순차 계산이 필요합니다.

SQL에서이 작업을 수행하는 방법에 대한 도움이 있으면 대단히 감사하겠습니다. 감사.

+0

가 대 "에서"를 표시하는 열이 있는가 "아웃"(즉, 현재 당신은 기록의 짝수가있는 가정 레지스터의 방향). 또한 "DateTime"은 실제로 시간 차이뿐입니다. 즉 시간과 같이 다른 데이터 유형의 열이어야합니까? – StuartLC

+0

안녕하세요 스튜어트, 귀하의 의견에 감사드립니다. 열 "TimeRegister1"은 "IN"열입니다 (오늘의 처음 시간 등록 - 항상 IN). 때로는 시간 기록표가없는 경우도 있습니다 (예 : 직원이 체크인했지만 체크 아웃을 잊어 버린 경우). 이 사건은 물론 무시해야합니다. 직원이 점심 시간에 체크 아웃했다가 다시 돌아올 때 IN을 체크하는 것을 잊었다 고 가정 해 봅시다. 그가 하루의 끝에서 체크 아웃하면 CHECK IN으로 간주됩니다. 이상은 수동으로 처리됩니다 (즉, 잊어 버린 체크인/체크 아웃 추가). 그에 따라 다시 계산됩니다. – Strat2014

+1

정말 열악한 테이블 디자인입니다.데이터를 생각하기보다는 물리적 인 형태로 디자인 된 것 같습니다. 이상적으로 이러한 datetime 값은 모두 단일 열에 있으며 각 항목마다 별도의 행이 있어야합니다. 당신은이 데이터에 대해'UNPIVOT'을 먼저 수행함으로써 이것을 근사시킬 수 있습니다. –

답변

0

제시된 표가 올바르다 고 가정하면 (예 : 30 열) DATEDIFF DateTimes를 입력하고 차이점을 함께 추가 한 다음 시간대 중 하나의 기준 날짜에 다시 추가합니다 (모든 가정 DateTimes는 같은 날에 있습니다). diff/add 해상도로 분을 선택하여 초를 제거 할 수 있습니다. 누락 된 데이터를 처리하려면 각 In/Out 쌍마다 ISNULL() 또는 COALESCE이 필요합니다.

SELECT Employee, TimeRegister1, TimeRegister2, TimeRegister3, TimeRegister4, 
     DATEADD(mi, ISNULL(DATEDIFF(mi, TimeRegister1, TimeRegister2), 0) 
       + ISNULL(DATEDIFF(mi, TimeRegister3, TimeRegister4), 0), 
       CAST(CAST(TimeRegister1 AS DATE) AS DATETIME)) 
     as CALCULATEDCOL   
FROM TimeRegister; 

주석에 따라 경찰, 약자로, CALCULATEDCOL 전혀 시점을 표현하지 않기 때문에, 별도의 날짜 및 시간 구성 요소로 CALCULATEDCOL을 분할하는 것이 더있을 수 있습니다.

SqlFiddle here

당신이 진정으로 30 열까지있는 경우 In/Out 데이터의 각 쌍에 대해 계산을 반복해야합니다 (직원 이상 15 회/일 건물을 떠나지 않는 희망!) .

편집
직원은 클럭하지 않은 데이터를 (달리 데이터가 쓸모 옆) 방향이 얻어 질 수 있다고 가정하고, 폐기/출력 데이터 클록의 원시 테이블 이렇게하려면 에서 밖으로 연속적으로, 같은 날에, 방법에 대해 :

WITH cte AS 
(
    SELECT Employee, 
      TimeRegister, 
      Direction, 
      CAST(TimeRegister AS DATE) AS TheDate, 
      ROW_NUMBER() OVER (PARTITION BY Employee, CAST(TimeRegister AS DATE) 
          ORDER BY TimeRegister ASC) AS Rnk 
    FROM TimeRegister 
) 
SELECT 
    cur.Employee, 
    DATEADD(mi, SUM(DATEDIFF(mi, cur.TimeRegister, nxt.TimeRegister)), 
      CAST(cur.TheDate AS DATETIME)) AS CALCULATEDCOL 
    FROM cte cur 
     INNER JOIN cte nxt 
     ON cur.Employee = nxt.Employee 
     AND cur.TheDate = nxt.TheDate AND cur.Rnk + 1 = nxt.Rnk 
    WHERE cur.Direction = 'I' AND nxt.Direction = 'O' 
    GROUP BY cur.Employee, cur.TheDate; 

SqlFiddle here

+1

그레이트 !!! 모든 도움을 주셔서 대단히 감사합니다! – Strat2014