我有一张时间卡表供员工上班/下班,布局如下:
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
请注意:
04:00:00
到03:59:59
(即上例中,全部归类为24/09/2013
)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 :(得分: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
答案 1 :(得分: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'
然后你可以通过计算时钟输入和时钟输出时间来获得时间。
有很多角落案件,并非全部处理:
但是没有时钟输出的情况是处理。由于分区的最后一行的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'
它更复杂,效率更低,但在无效的“输入”和“输出”序列中更加强大。然后,它处理无效序列的方式可能是也可能不是你真正想要的行为。