我有一张表attendance
|AttendanceresultId | AccountID | Intime | Outtime | ShiftID |
| 1 | 1234 | 2016-06-21 06:56:00 | NULL | 1 |
| 2 | 1234 | NULL | 2016-06-21 17:02:00 | 1 |
| 3 | 1234 | 2016-06-22 06:56:00 | NULL | 1 |
| 4 | 1234 | NULL | 2016-06-22 17:02:00 | 1 |
| 5 | 1235 | 2016-06-21 22:55:00 | NULL | 3 |
| 6 | 1235 | NULL | 2016-06-22 06:00:00 | 3 |
| 7 | 1235 | 2016-06-22 22:55:00 | NULL | 3 |
| 8 | 1235 | NULL | 2016-06-23 07:00:00 | 3 |
另一张表是shift
表
| ShiftId | Starttime | Endtime |
| 1 | 07:00:00.00 | 16:00:00.00 |
| 3 | 23:00:00.00 | 06:00:00.00 |
我想计算员工的工作时间总数和时间,例如
预期产出,
| AccountID | NormalHours | OvertimeHours |
| 1234 | 18:08 Hrs | 02:04 Hrs |
| 1235 | 14:10 Hrs | 01:00 Hrs |
我是sql server中的新手可以任何人提出任何建议
答案 0 :(得分:0)
我把它分成了四个部分来调整2008年缺乏滞后功能:
1)用于组织记录的公用表表达式(以便不依赖于身份字段)
2)在不使用滞后函数的情况下计算加班时间和加班时间
3)然后我总结那些会议记录 - 并将它们分成几小时和几分钟。
4)然后我格式化它们。
也就是说,我认为现实世界数据可能会产生问题。
更新了不使用滞后功能的版本
WITH TimeRecords (AccountID, InOutTime, Intime, OutTime, Shift,
RowNumber) AS
(SELECT att.AccountID, COALESCE(att.Intime,att.OutTime),
att.Intime, att.OutTime, att.Shift,
ROW_NUMBER() OVER(ORDER BY att.AccountID,
COALESCE(att.InTime, att.OutTime) )
FROM dbo.attendance att)
,
ShiftTime AS (
SELECT trecout.AccountID ,
trecin.InTime,
trecout.OutTime,
-- sh.EndTime ,
-- Number of Minutes for the entire shift
CASE WHEN trecout.OutTime IS NOT NULL
THEN DATEDIFF(mi,
trecin.InTime,
trecout.OutTime)
ELSE 0
END AS TotalTime ,
-- Number of Minutes for overtime
CASE WHEN trecout.OutTime IS NOT NULL
THEN DATEDIFF(mi, sh.EndTime,
CAST(trecout.OutTime AS TIME))
ELSE 0
END AS OverTime
FROM TimeRecords trecout
JOIN TimeRecords trecin
ON trecout.RowNumber -1 = trecin.RowNumber
JOIN dbo.ShiftID sh
ON trecout.[Shift] = sh.ShiftID
)
,
-- Summarize the data
ShiftTimeSum
AS ( SELECT st.AccountID ,
FLOOR(SUM(st.TotalTime - st.OverTime) / 60) AS RegularHours ,
SUM(st.TotalTime - st.OverTime) % 60 AS RegularMinutes ,
SUM(st.OverTime) / 60 AS OverTimeHours ,
SUM(st.OverTime) % 60 AS OverTimeMinutes
FROM ShiftTime st
GROUP BY st.AccountID
)
-- Now format
SELECT sts.AccountID ,
CAST(sts.RegularHours AS VARCHAR(5)) + ':'
+ RIGHT(CAST(( 100 + sts.RegularMinutes ) AS CHAR(3)), 2) AS RegularTime ,
CAST(sts.OverTimeHours AS VARCHAR(5)) + ':'
+ RIGHT(CAST(( 100 + sts.OverTimeMinutes ) AS CHAR(3)), 2) AS OverTime
FROM ShiftTimeSum sts;