我有几个问题有关如何处理SQL 2012中的一些员工计时查询…我上周询问了另一个Quesiton,以确定两次班次之间的时间对。
的很好回应我们是从销售点软件提供商中喂养数据的,因此我们无法更改数据的格式。
工作日是基于从5:00上午5:00到下一个日历日上午4:59的日期,因此它越过午夜。位置结束过程有点偏移以控制平衡负载,有些是上午5:05,而不是上午5:00。当一天的结束过程结束时,它会将每个人都计时,然后在过程完成后将其回到。 - 员工在30分钟的需要休息时将其钟表时间,因此这些员工一天有2个或更多记录。不确定为什么,但是有几个员工在一天内拥有超过3个记录(imhereeeShiftNumber)。 - 偶尔转移约会。在11:00 pm-上午7:00
我需要报告初始intime和最后的耗时列表以及工作的分钟数。我将不得不将这些与持有员工时间表的表进行比较。该报告不是出于薪资目的,而是用于与预定班次的比较。
我包含了一些由员工分组的示例数据,以及我希望看到的值对右边的评论。我还需要查看轮班中的分钟数。
--drop table #Shift
CREATE TABLE #Shift(
FKEmployeeNumber int,
DateOfBusiness datetime,
FKStoreId int,
EmployeeShiftNumber int,
FKJobCodeId int,
InHour int,
InMinute int,
OutHour int,
OutMinute int)
insert into #Shift ( FKEmployeeNumber, DateOfBusiness, FKStoreId, EmployeeShiftNumber, FKJobCodeId, InHour, InMinute,OutHour,OutMinute)
values
(23761, '11/30/2017', 3013, 0, 1, 17, 39, 21, 30),
(23761, '11/30/2017', 3013, 1, 1, 21, 30, 2, 39), -- 5:39PM 2:39AM
(23770, '11/30/2017', 3013, 0, 200, 7, 19, 16, 25), -- 7:19AM 4:25PM
(23938, '11/30/2017', 3013, 0, 1, 16, 4, 1, 26), -- 4:04AM 1:26AM
(24006, '11/30/2017', 3013, 0, 1, 7, 30, 18, 36),
(24006, '11/30/2017', 3013, 1, 1, 18, 36, 18, 40), -- 7:30AM 6:40PM
(24018, '11/30/2017', 3013, 0, 2, 8, 52, 17, 0), -- 8:52M 4:00PM
(25176, '11/30/2017', 3013, 0, 200, 15, 59, 20, 1), -- 3:59PM 8:01PM
(25176, '11/30/2017', 3013, 1, 200, 20, 30, 0, 05), -- 8:30PM 12:05AM
(25180, '11/30/2017', 3013, 0, 1, 21, 0, 5, 0), -- 9:00PM 5:00AM
(25187, '11/30/2017', 3013, 0, 1, 10, 0, 16, 6), -- 10:00AM 4:06PM
(35189, '11/30/2017', 3013, 0, 1, 16, 58, 2, 4), -- 4:58PM 2:04AM
(25147, '12/04/2017', 3106, 0, 1, 6, 58, 15, 2),
(25147, '12/04/2017', 3106, 1, 1, 15, 3, 15, 3), -- 6:58AM 3:03PM
(26291, '12/01/2017', 3118, 1, 200, 23, 15, 5, 5),
(26291, '12/02/2017', 3118, 0, 200, 5, 6, 7, 22), -- 11:15PM 7:22AM
(26291, '12/03/2017', 3118, 0, 200, 7, 30, 15, 38), -- 7:30AM 3:38PM
(26291, '12/04/2017', 3118, 0, 200, 23, 15, 5, 5),
(26291, '12/05/2017', 3118, 0, 200, 5, 6, 7, 12), -- 11:15PM 7:12AM
(26291, '12/05/2017', 3118, 1, 200, 23, 15, 5, 5),
(26291, '12/06/2017', 3118, 0, 200, 15, 14, 7, 5) -- 11:15PM 7:05AM
--Select * from #Shift
SELECT fkstoreid, FKEmployeeNumber AS EmpID, DateOfBusiness AS Date,
RIGHT(CONVERT(varchar(30), DATEADD(MINUTE, InTime_Mins, 0), 100), 7) AS InTime,
RIGHT(CONVERT(varchar(30), DATEADD(MINUTE, OutTime_Mins, 0), 100), 7) AS OutTime,
MinsWorked
FROM (
select sh.FKStoreId, sh.FKEmployeeNumber, sh.DateOfBusiness,
MIN(sh.InHour*60+InMinute) AS InTime_Mins,
MAX(sh.OutHour*60+OutMinute) AS OutTime_Mins,
SUM(((sh.outhour+case when sh.OutHour < sh.InHour then 24 else 0 end)*60 + sh.outminute) -
(sh.inhour*60 + sh.inminute)) AS MinsWorked
from #shift sh
group by sh.FKStoreId,sh.FKEmployeeNumber, sh.DateOfBusiness
) AS derived
order by FKEmployeeNumber, DateOfBusiness
我已经写了一个如何做的样本。
简短地总结了我执行以下步骤:
- 标记记录应与下一个记录或上一个记录分组,因为它们是同一轮班的一部分。
- 找到每个班次的开始和结束
- 加入属于每个班次的员工的所有记录
- 将每个换班者的每个员工的结果集组小组,并通过将班次内的每个记录的检查和结帐之间的分钟进行总结。
样本查询:
WITH ShiftParts AS (
SELECT
FKEmployeeNumber,
DATEADD(MINUTE, InMinute, DATEADD(HOUR, InHour, DateOfBusiness)) CheckIn, --Datetime of the checkin
DATEADD(DAY, CASE WHEN OutHour < InHour THEN 1 ELSE 0 END,
DATEADD(MINUTE, OutMinute, DATEADD(HOUR, OutHour, DateOfBusiness))) CheckOut --Datetime of the checkout (add one day if we crossed midnight).
FROM #Shift
),
GroupInfo AS (
SELECT
*,
CASE
WHEN DATEDIFF(MINUTE, LAG(CheckOut, 1, NULL) OVER (PARTITION BY FKEmployeeNumber ORDER BY CheckOut), CheckIn) <= 120
THEN 1 ELSE 0 END AS GroupWithPrevious, --Determine whether we want to group this record with the previous
CASE
WHEN DATEDIFF(MINUTE, CheckOut, LEAD(CheckIn, 1, NULL) OVER (PARTITION BY FKEmployeeNumber ORDER BY CheckOut)) <= 120
THEN 1 ELSE 0 END AS GroupWithNext --Determine whether we want to group this record with the next
FROM ShiftParts
), ShiftStartAndEnd AS (
SELECT
*,
CASE WHEN GroupWithNext = 1 THEN LEAD(CheckOut, 1, NULL) OVER (PARTITION BY FKEmployeeNumber ORDER BY CheckOut) ELSE CheckOut END AS FinalCheckOut
FROM GroupInfo
WHERE GroupWithPrevious = 0 OR GroupWithNext = 0 --Only pick beginning and end of a shift
)
SELECT
sse.FKEmployeeNumber,
sse.CheckIn,
sse.FinalCheckOut,
SUM(DATEDIFF(MINUTE,sp.CheckIn,sp.CheckOut)) AS MinutesWorked
FROM ShiftStartAndEnd sse
LEFT OUTER JOIN ShiftParts sp ON sp.FKEmployeeNumber = sse.FKEmployeeNumber AND sp.CheckIn >= sse.CheckIn AND sp.CheckOut <= sse.FinalCheckOut
WHERE sse.GroupWithPrevious = 0
GROUP BY sse.FKEmployeeNumber, sse.CheckIn, sse.FinalCheckOut
注意:我认为您的示例数据中的最后两个记录不应分组
(26291, '12/05/2017', 3118, 1, 200, 23, 15, 5, 5),
(26291, '12/06/2017', 3118, 0, 200, 15, 14, 7, 5) -- 11:15PM 7:05AM
应该是:
(26291, '12/05/2017', 3118, 1, 200, 23, 15, 5, 5), -- 11:19PM 5:05AM
(26291, '12/06/2017', 3118, 0, 200, 15, 14, 7, 5) -- 3:14PM 7:05AM