2013-09-25 43 views
4

我有一個考勤表,工作人員時鐘輸入/輸出,佈局如下:查詢一個考勤數據庫

employeeID Clock-in DateTime Clock Type 
1004  24/09/2013 13:08 in 
1004  25/09/2013 00:50 out 
1005  24/09/2013 12:08 in 
1005  25/09/2013 03:55 out 
2003  24/09/2013 10:06 in 
2003  24/09/2013 15:42 out 
2003  24/09/2013 17:33 in 
2003  24/09/2013 22:17 out 

我怎樣才能得到它是這樣的:

Date  employeeID Clock-in   Clock-out   time worked (in hours to 2 decimal place) 
24/09/2013 1004  24/09/2013 13:08 25/09/2013 00:50 xx.xx 
24/09/2013 1005  24/09/2013 12:08 25/09/2013 03:55 xx.xx 
24/09/2013 2003  24/09/2013 10:06 24/09/2013 15:42 xx.xx 
24/09/2013 2003  24/09/2013 17:33 24/09/2013 22:17 xx.xx 

注意:

  1. 員工可以在輸入/輸出(即上午/下午,夜班)多個時鐘
  2. 日期從04:00:0003:59:59(即,在上面的例子中,所有分類爲24/09/2013
  3. 我怎樣才能處理記錄沒有時鐘?我可以設置類似如果null,時間等於下一個日期03:59:59

在此先感謝。

我更新了jods建議如下:

例3

套進/出記錄

EmployeeID CardDate   PunchType 
1000  21/09/2013 07:43 in 
1000  21/09/2013 11:29 out 
1000  21/09/2013 12:39 in 
1000  21/09/2013 20:37 out 
1000  21/09/2013 21:58 in 
1000  22/09/2013 00:16 out 

查詢返回

Date  EmployeeID clockInTime clockOutTime 
21/09/2013 1000  07:43:57 00:16:22 
21/09/2013 1000  21:58:40 11:29:22 
+0

這張桌子上沒有PK嗎?或者,一個給定的員工是否可以在一分鐘內不進入/退出 - 使整個記錄具有唯一性。 – Orbling

+1

和你正在使用哪個版本的sqlserver?它有所作爲 –

+0

表中有一個主鍵,但它有某種哈希。時鐘/輸入和時鐘/輸出在第二,因此每個記錄是唯一的 – user549410

回答

0

如果使用SQL Server 2005和以上。你可以試試這個

WITH cte AS (
SELECT 
    [employeeID] 
    ,ti.ClockIn 
    ,ClockOut = (SELECT MIN(t.ClockIn) 
       FROM timecard t 
       WHERE ti.employeeID = t.employeeID 
       AND t.Type = 'out' 
       AND t.ClockIn > ti.ClockIn 
       AND t.ClockIn < DATEADD(hour, 24 + 4 , CAST(CAST(ti.ClockIn AS DATE) AS datetime)) 
       ) 
    ,NextDayLimit = DATEADD(SECOND, -1, DATEADD(hour, 24 + 4 , CAST(CAST(ti.ClockIn AS DATE) AS datetime))) 
FROM timecard ti 
WHERE Type = 'in' 
) 
SELECT 
    employeeID, 
    ClockIn, 
    ISNULL(ClockOut, NextDayLimit) AS ClockOut, 
    CAST(DATEDIFF(minute, ClockIn, ISNULL(ClockOut, NextDayLimit))/60.0 AS NUMERIC(19,2)) AS TimeWorked 
from cte 
ORDER BY employeeID, ClockIn 
+0

我試過你的解決方案,它可以與工作人員一起工作,最多2個clockin/clockout(4條記錄),但是我有一個員工有3組輸入/輸出,並且在輸入和輸出記錄中有一個錯誤匹配。我已經把一些樣品原始數據和結果集返回供您參考 – user549410

+0

它的工作原理,謝謝。 – user549410

0

如果使用SQL 2012,這是一個使用LEAD的基本思想:

SELECT 
    ROUND(clockIn) as [date], 
    employeeId, 
    clockIn as clockInTime, 
    LEAD(clockIn) OVER (PARTITION BY employeeId, ROUND(clockIn) ORDER BY clockIn) as clockOutTime 
FROM TimeCard 
WHERE clockType = 'in' 

然後,您可以在做和時鐘輸出時間時鐘之間的差異獲取時間。

有很多角落的情況下,並非所有在這裏處理:

  • 可以工期跨度午夜?
  • 如果第一次輸入是「輸出」類型,該怎麼辦?
  • 如果連續有兩個「in」或兩個「out」,該怎麼辦?

雖然沒有時鐘輸出的情況下處理。由於分區的最後一行的LEAD值爲NULL。

下面是在SQL 2005的作品更穩健的選擇:

WITH NumberedClockIn AS (
    SELECT 
    ROUND(clockIn) as [date], 
    employeeId, 
    clockIn as clockTime, 
    clockType, 
    ROW_NUMBER() OVER (PARTITION BY employeeId, ROUND(clockIn) ORDER BY clockIn) as rn 
    FROM TimeCard 
) 
SELECT 
    IN.[date], 
    IN.employeeId, 
    IN.clockTime as clockInTime, 
    OUT.clockTime as clockOutTime 
FROM NumberedClockIn IN 
LEFT OUTER JOIN NumberedClockIn OUT 
    ON IN.[date] = OUT.[date] 
AND IN.employeeId = OUT.employeeID 
AND IN.rn + 1 = OUT.rn 
WHERE IN.clockType = 'in' 
    AND OUT.clockType = 'out' 

它更復雜,效率較低,但在「在」臉的無效和「出」的序列更加穩健。再次,它處理無效序列的方式可能會或可能不是您實際需要的行爲。