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:00まで03:59:59(つまり、上記の例では、すべて として分類されます24/09/2013)
  3. 退勤時間のないレコードを処理するにはどうすればよいですか? if null、 time equals to next date のようなものを設定できます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
4

2 に答える 2

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
于 2013-09-25T20:16:05.610 に答える
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'

次に、出勤時間と退勤時間の差をとることで時間を取得できます。

多くのコーナーケースがあり、すべてがここで扱われるわけではありません:

  • 作業期間が深夜にまたがることはありますか?
  • 最初の出勤のタイプが「出勤」の場合はどうなりますか?
  • 行に 2 つの「in」または 2 つの「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'

より複雑で効率は劣りますが、無効な 'in' および 'out' シーケンスに直面した場合の堅牢性は向上します。繰り返しますが、無効なシーケンスを処理する方法は、実際に必要な動作である場合とそうでない場合があります。

于 2013-09-25T21:30:31.740 に答える