2017-08-29 68 views
3

我有一個包含進入和退出事件的EVENT表。我計算工作時間與步驟:當記錄重複時修復交叉應用行

SET @worktime = (SELECT SUM(mins) 
       FROM 
        (SELECT 
          entry.EmployeeId, entry.DateTime AS EntryDateTime, 
          [exit].DateTime AS ExitDateTime, DATEDIFF(MINUTE, entry.DateTime, [exit].DateTime) AS mins 
         FROM 
          Events entry 
         CROSS APPLY 
          (SELECT TOP 1 e.DateTime 
          FROM Events e 
          WHERE e.EmployeeId = entry.EmployeeId 
          AND e.DateTime > entry.DateTime 
          AND e.EventTypeID = 2 
          AND CAST(e.DateTime AS DATE) = CAST(@data AS DATE) 
          AND e.ControlPointID IN (SELECT ControlPointID 
                 FROM ControlPoints 
                 INNER JOIN dbo.Split(RIGHT(@rcp, LEN(@rcp) - 2), ';') AS split ON ControlPoints.NAme = split.Data + ' EXIT') 
          ORDER BY e.DateTime ASC) AS [exit] 
         WHERE 
          entry.EventTypeId = 1 
          AND EmployeeId = @code 
          AND CAST(entry.DateTime AS DATE) = CAST(@data AS DATE) 
          AND ControlPointID IN (SELECT ControlPointID 
               FROM ControlPoints 
               INNER JOIN dbo.Split(RIGHT(@rcp, LEN(@rcp) - 2), ';') AS split ON ControlPoints.NAme = split.Data + ' ENTRY') 
                               AND CAST(entry.[DateTime] AS DATE) = CAST(@data AS DATE)) AS input 
       GROUP BY EmployeeId) 

例如,如果有兩個輸入和一些員工兩個出口的事件,它可以完美運行。但是,如果有一個退出和兩個輸入事件,它不會像我想工作一樣。

示例:員工XXX在05:44工作,然後他在06:28退出。之後他在06:50回來,並在12:33再次退出。此過程應返回@worktime等於387分鐘。

第二天他犯了一個錯誤,他在06:00工作,但在EVENTS表中有兩個相同的記錄。他在14:00退出(只有exit記錄在EVENT表中)。程序返回960分鐘。我想,如果它返回480.

當輸入事件數量不等於退出事件數量(例如:2進入和1退出)時,如何修復交叉應用?

帶圖像的例子:

下面的例子很完美。

Working Example

選定行(1,4,5,8)被傳遞給程序。 ControlPointId = 6是入口點,ControlPointId = 3是退出點。 EventTypeId = 1是輸入事件,EventTypeId = 2是退出。

但是,這並不工作:

Not Working

在這種情況下,ControlPointId = 64的入口點和ControlPointId = 56是出口點。我們可以看到,這個Employee出錯了,ControlPoint兩次讀了他的卡片,所以有2個入口事件和1個出口事件。

我該如何更改程序?當出現像這樣的錯誤時(或者相反的情況:1入口和2出口事件),它應該只進入第一個入口事件。

+3

任何方式,我們可以得到的架構和一些數據來看看,並幫助找出其中的問題可能是。 – ttallierchio

+0

@ttallierchio請參閱編輯 – fanarek

+0

嘗試對入口和出口進行排名,然後分別使用第一個入口和出口。 –

回答

1

你可以試試這個。如果不同的入口事件具有相同的退出事件,我把第一個條目使用ROW_NUMBER

SET @worktime = (SELECT SUM(mins) 
       FROM 
        (SELECT 
          entry.EmployeeId, entry.DateTime AS EntryDateTime, 
          [exit].DateTime AS ExitDateTime, 
          DATEDIFF(MINUTE, entry.DateTime, [exit].DateTime) AS mins, 
          RN = ROW_NUMBER() OVER (PARTITION BY [exit].EventID ORDER BY entry.DateTime) 
         FROM 
          Events entry 
         CROSS APPLY 
          (SELECT TOP 1 e.DateTime, e.EventID 
          FROM Events e 
          WHERE e.EmployeeId = entry.EmployeeId 
          AND e.DateTime > entry.DateTime 
          AND e.EventTypeID = 2 
          AND CAST(e.DateTime AS DATE) = CAST(@data AS DATE) 
          AND e.ControlPointID IN (SELECT ControlPointID 
                 FROM ControlPoints 
                 INNER JOIN dbo.Split(RIGHT(@rcp, LEN(@rcp) - 2), ';') AS split ON ControlPoints.NAme = split.Data + ' EXIT') 
          ORDER BY e.DateTime ASC) AS [exit] 
         WHERE 
          entry.EventTypeId = 1 
          AND EmployeeId = @code 
          AND CAST(entry.DateTime AS DATE) = CAST(@data AS DATE) 
          AND ControlPointID IN (SELECT ControlPointID 
               FROM ControlPoints 
               INNER JOIN dbo.Split(RIGHT(@rcp, LEN(@rcp) - 2), ';') AS split ON ControlPoints.NAme = split.Data + ' ENTRY') 
                               AND CAST(entry.[DateTime] AS DATE) = CAST(@data AS DATE)) AS input 
       WHERE RN = 1 
       GROUP BY EmployeeId) 
+0

它的工作原理。完美!謝謝。 – fanarek

+0

不客氣! –