我正在尝试在SQL Server 2012中创建一个查询来计算First IN和&之间的时差。公司中每位员工的最后一次刷卡(正常的白班和夜班)。下面是我查询的样本数据。
Create table #TempData (EmpName nvarchar(50),EventDateTime DateTime, TrnName nvarchar(20),TrnCode int)
Insert Into #TempData Values
('User1','2015-08-04 09:10:53','Entrance','0'),
('User1','2015-08-04 10:43:52','Exit','1'),
('User1','2015-08-04 11:13:23','Entrance','0'),
('User1','2015-08-04 13:32:29','Exit','1'),
('User1','2015-08-05 09:46:19','Exit','1'),
('User1','2015-08-05 10:22:28','Entrance','0'),
('User1','2015-08-06 18:47:02','Exit','1'),
('User1','2015-08-06 19:29:02','Entrance','0'),
('User1','2015-08-06 21:05:26','Exit','1'),
('User1','2015-08-18 11:54:42','Entrance','0'),
('User1','2015-08-18 19:19:02','Exit','1'),
('User1','2015-08-18 20:15:01','Entrance','0'),
('User1','2015-08-18 20:57:49','Exit','1'),
('User1','2015-08-19 12:10:48','Entrance','0'),
('User1','2015-08-20 11:57:04','Entrance','0'),
('User1','2015-08-20 20:57:19','Exit','1'),
('User1','2015-08-24 18:14:26','Entrance','0'),
('User1','2015-08-25 02:28:31','Exit','1'),
('User1','2015-08-28 17:14:05','Entrance','0'),
('User1','2015-08-29 04:50:28','Exit','1'),
('User1','2015-09-03 17:40:53','Entrance','0'),
('User1','2015-09-04 02:42:57','Exit','1'),
('User1','2015-09-04 18:27:25','Entrance','0'),
('User1','2015-09-04 18:27:29','Entrance','0'),
('User1','2015-09-05 02:32:31','Exit','1'),
('User1','2015-09-07 10:58:24','Entrance','0'),
('User1','2015-09-07 14:04:54','Entrance','0'),
('User1','2015-09-07 17:55:52','Exit','1'),
('User1','2015-09-08 17:51:20','Entrance','0'),
('User1','2015-09-09 02:25:20','Exit','1')
以下是我正在使用的查询。
;with cte as
(
select
ROW_NUMBER() over(order by EmpName,EventDateTime) rn,
EmpName, EventDateTime,
cast(EventDateTime as date) EventDate,
TrnName,TrnCode
from #TempData
)
,ctee
as
(
select
Ent.rn as Ent_Rn, Ent.EmpName as Ent_EmpName,
Ent.EventDate as Ent_EventDate, Ent.EventDateTime as Ent_EventDateTime,
Ex.rn as Ex_Rn,EX.EmpName as Ex_EmpName,
Ex.EventDate as Ex_EventDate, Ex.EventDateTime as Ex_EventDateTime
from
(
select
*
from cte
where TrnName = 'Entrance'
) as Ent
full join
(
select
*
from cte
where TrnName = 'Exit'
) as Ex
on Ent.rn+1 = Ex.rn and Ent.EmpName = Ex.EmpName
)
,cteee
as
(
select
case when Ent_EmpName is null then Ex_EmpName
else Ent_EmpName
end as EmpName,
Ent_EventDateTime as LoginTime,
case
when DATEDIFF(hour, cast(Ent_EventDateTime as datetime), cast(Ex_EventDateTime as datetime))>14 then null
else Ex_EventDateTime
end as LogoutTime
from ctee
)
select
*,
DATEDIFF(second,LoginTime,LogoutTime) As Seconds
,TIMEFROMPARTS(((DATEDIFF(second,LoginTime,LogoutTime))%(3600*24)/3600),
(((DATEDIFF(second,LoginTime,LogoutTime))%(3600*24)%3600)/60),
(((DATEDIFF(second,LoginTime,LogoutTime))%(3600*24)%3600)%60),0, 0) AS WorkTime
from cteee order by EmpName, LoginTime
然而,这是不正确的,因为这反映了每个IN&之间的实际时间。 OUT并为任何错过的IN / OUT输入NULL。但要求是为员工提供第一个IN和最后一个OUT(正常和夜班时间),无论多个IN& OUT IN& 1st之间的OUT最后OUT。但是,如果缺少任何IN或OUT或任何IN和OUT之间的时间差超过14小时,则将其标记为NULL。 以下是预期结果。
添加更多数据和结果反映结果不正确,因此需要修改NEER提供的查询。
数据:
('User1','2015-07-20 11:07:29','Entrance','0'),
('User1','2015-07-20 11:08:09','Exit','1'),
('User1','2015-07-20 21:13:27','Exit','1'),
('User1','2015-07-21 12:07:03','Entrance','0'),
('User1','2015-07-21 21:04:02','Exit','1'),
('User1','2015-07-22 11:48:06','Entrance','0'),
('User1','2015-07-22 13:37:15','Exit','1'),
('User1','2015-07-22 13:57:58','Entrance','0'),
('User1','2015-07-22 20:59:22','Exit','1'),
('User1','2015-07-23 12:38:41','Entrance','0'),
('User1','2015-07-23 17:33:43','Exit','1'),
('User1','2015-07-23 18:09:13','Entrance','0'),
('User1','2015-07-23 21:03:13','Exit','1'),
('User1','2015-07-24 11:51:03','Entrance','0'),
('User1','2015-07-24 14:19:41','Exit','1'),
('User1','2015-07-24 14:36:55','Entrance','0'),
('User1','2015-07-24 20:51:06','Exit','1'),
('User1','2015-07-27 12:10:54','Entrance','0'),
('User1','2015-07-27 17:45:36','Exit','1'),
('User1','2015-07-27 18:36:24','Entrance','0'),
('User1','2015-07-27 19:16:21','Exit','1'),
('User1','2015-07-27 20:01:12','Entrance','0'),
('User1','2015-07-27 21:04:47','Exit','1'),
('User1','2015-07-28 11:24:09','Entrance','0'),
('User1','2015-07-28 21:05:32','Exit','1'),
('User1','2015-07-29 12:03:09','Entrance','0'),
('User1','2015-07-29 18:36:07','Exit','1'),
('User1','2015-07-29 19:25:16','Entrance','0'),
('User1','2015-07-29 21:00:28','Exit','1'),
('User1','2015-07-30 11:58:43','Entrance','0'),
('User1','2015-07-30 13:09:18','Exit','1'),
('User1','2015-07-30 13:25:02','Entrance','0'),
('User1','2015-07-30 21:00:20','Exit','1'),
('User1','2015-07-31 12:11:36','Entrance','0'),
('User1','2015-07-31 19:46:47','Exit','1'),
('User1','2015-07-31 20:44:27','Entrance','0'),
('User1','2015-07-31 21:34:07','Exit','1')
答案 0 :(得分:1)
尝试如下:
declare @TempData Table (EmpName nvarchar(50),EventDateTime DateTime, TrnName nvarchar(20),TrnCode int)
Insert Into @TempData Values
('User1','2015-08-04 09:10:53','Entrance','0'),
('User1','2015-08-04 10:43:52','Exit','1'),
('User1','2015-08-04 11:13:23','Entrance','0'),
('User1','2015-08-04 13:32:29','Exit','1'),
('User1','2015-08-05 09:46:19','Exit','1'),
('User1','2015-08-05 10:22:28','Entrance','0'),
('User1','2015-08-06 18:47:02','Exit','1'),
('User1','2015-08-06 19:29:02','Entrance','0'),
('User1','2015-08-06 21:05:26','Exit','1'),
('User1','2015-08-18 11:54:42','Entrance','0'),
('User1','2015-08-18 19:19:02','Exit','1'),
('User1','2015-08-18 20:15:01','Entrance','0'),
('User1','2015-08-18 20:57:49','Exit','1'),
('User1','2015-08-19 12:10:48','Entrance','0'),
('User1','2015-08-20 11:57:04','Entrance','0'),
('User1','2015-08-20 20:57:19','Exit','1'),
('User1','2015-08-24 18:14:26','Entrance','0'),
('User1','2015-08-25 02:28:31','Exit','1'),
('User1','2015-08-28 17:14:05','Entrance','0'),
('User1','2015-08-29 04:50:28','Exit','1'),
('User1','2015-09-03 17:40:53','Entrance','0'),
('User1','2015-09-04 02:42:57','Exit','1'),
('User1','2015-09-04 18:27:25','Entrance','0'),
('User1','2015-09-04 18:27:29','Entrance','0'),
('User1','2015-09-05 02:32:31','Exit','1'),
('User1','2015-09-07 10:58:24','Entrance','0'),
('User1','2015-09-07 14:04:54','Entrance','0'),
('User1','2015-09-07 17:55:52','Exit','1'),
('User1','2015-09-08 17:51:20','Entrance','0'),
('User1','2015-09-09 02:25:20','Exit','1'),
('B','2016-06-22 17:27:00','Exit','1'),
('B','2016-06-22 17:42:01','Entrance','0'),
('B','2016-06-22 21:27:59','Exit','1'),
('B','2016-06-22 21:45:47','Exit','1'),
('B','2016-06-22 21:56:15','Entrance','0'),
('B','2016-06-23 00:42:44','Exit','1'),
('B','2016-06-23 01:03:06','Entrance','0'),
('B','2016-06-23 02:47:18','Exit','1')
;WITH CTE1
AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY CAST(T.EventDateTime AS DATE)) AS RowId
FROM
@TempData T
), CTE2
AS
(
SELECT
A.EmpName,
A.EventDateTime,
A.TrnName,
A.TrnCode,
DENSE_RANK() OVER (ORDER BY MIN(B.RowId)) [Group]
FROM
CTE1 A CROSS JOIN CTE1 B
WHERE
ABS(DATEDIFF(HOUR, A.EventDateTime, B.EventDateTime)) BETWEEN 0 AND 14 -- Here
GROUP BY
A.EmpName,
A.EventDateTime,
A.TrnName,
A.TrnCode
), CTE3
AS
(
SELECT
T.EmpName,
MIN(IIF(T.TrnCode = 0, T.EventDateTime, NULL)) InDate,
MAX(IIF(T.TrnCode = 1, T.EventDateTime, NULL)) OutDate
FROM
CTE2 T
GROUP BY
T.EmpName,
T.[Group]
), FinalTable
AS
(
SELECT
T.EmpName ,
T.InDate,
IIF(T.InDate > T.OutDate, NULL, T.OutDate) AS OutDate
FROM CTE3 T
UNION
SELECT
T.EmpName ,
IIF(T.InDate > T.OutDate, NULL, T.InDate) AS InDate,
T.OutDate AS OutDate
FROM CTE3 T
)
SELECT
F.EmpName ,
F.InDate ,
F.OutDate,
DATEDIFF(SECOND, F.InDate, F.OutDate) [Second],
CONVERT(CHAR(8),DATEADD(SECOND,DATEDIFF(SECOND,F.InDate,F.OutDate),'1900-1-1'),8) WorkTime
FROM
FinalTable F
结果:
EmpName InDate OutDate Second WorkTime
----------- ----------------------- ----------------------- ----------- --------
User1 NULL 2015-08-05 09:46:19.000 NULL NULL
User1 2015-08-04 09:10:53.000 2015-08-04 13:32:29.000 15696 04:21:36
User1 2015-08-05 10:22:28.000 NULL NULL NULL
User1 2015-08-06 19:29:02.000 2015-08-06 21:05:26.000 5784 01:36:24
User1 2015-08-18 11:54:42.000 2015-08-18 20:57:49.000 32587 09:03:07
User1 2015-08-19 12:10:48.000 NULL NULL NULL
User1 2015-08-20 11:57:04.000 2015-08-20 20:57:19.000 32415 09:00:15
User1 2015-08-24 18:14:26.000 2015-08-25 02:28:31.000 29645 08:14:05
User1 2015-08-28 17:14:05.000 2015-08-29 04:50:28.000 41783 11:36:23
User1 2015-09-03 17:40:53.000 2015-09-04 02:42:57.000 32524 09:02:04
User1 2015-09-04 18:27:25.000 2015-09-05 02:32:31.000 29106 08:05:06
User1 2015-09-07 10:58:24.000 2015-09-07 17:55:52.000 25048 06:57:28
User1 2015-09-08 17:51:20.000 2015-09-09 02:25:20.000 30840 08:34:00
B 2016-06-22 17:42:01.000 2016-06-23 02:47:18.000 32717 09:05:17
答案 1 :(得分:0)
您可以使用以下步骤计算每位员工的登录,注销和工作时间 1.1st为原始表中的数据处理创建临时表 2.来自该临时表的查询 3.表示临时表
Create table #Process_data (EmpName nvarchar(50),login_Time DateTime,logout_Time DateTime)
go
insert into #process_data(EmpName,login_Time)
select EmpName,MIN(EventDateTime) as login_Time from #TempData
where TrnCode =0
group by EmpName,CONVERT(date,EventDateTime)
go
update #process_data
set logout_Time=case when logout_Time is null
then ( SELECT
MAX(EventDateTime) FROM #TempData
where #TempData.EmpName= #process_data.EmpName
and CONVERT(date,#TempData.EventDateTime)=CONVERT(date,#process_data.login_Time)
and EventDateTime>login_Time
and TrnCode =1
)
else logout_Time end
go
select EmpName,login_Time,logout_time, datediff(second,login_time,logout_time) as[second],datediff(second,login_time,logout_time)/3600.0 as workingTime
from #process_data
EmpName login_Time logout_time second workingTime
User1 2015-08-04 09:10:53.000 2015-08-04 13:32:29.000 15696 4.360000
User1 2015-08-05 10:22:28.000 NULL NULL NULL
User1 2015-08-06 19:29:02.000 2015-08-06 21:05:26.000 5784 1.606666
User1 2015-08-18 11:54:42.000 2015-08-18 20:57:49.000 32587 9.051944
User1 2015-08-19 12:10:48.000 NULL NULL NULL
User1 2015-08-20 11:57:04.000 2015-08-20 20:57:19.000 32415 9.004166
User1 2015-08-24 18:14:26.000 NULL NULL NULL
User1 2015-08-28 17:14:05.000 NULL NULL NULL
User1 2015-09-03 17:40:53.000 NULL NULL NULL
User1 2015-09-04 18:27:25.000 NULL NULL NULL
User1 2015-09-07 10:58:24.000 2015-09-07 17:55:52.000 25048 6.957777
User1 2015-09-08 17:51:20.000 NULL NULL NULL
答案 2 :(得分:0)
SELECT FinalEntranceData.EmpName,FinalEntranceData.eventdatetime [LoginTime],FinalExitData.eventdatetime [LogoutTime],DATEDIFF(second,FinalEntranceData.eventdatetime,FinalExitData.eventdatetime) As Seconds FROM ( SELECT seqnumber,empName,eventdatetime FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY empName,CONVERT(VARCHAR(20),eventdatetime,112) ORDER BY eventdatetime)seqnumber,empname,eventdatetime FROM #TempData WHERE trnname ='Entrance' ) EntranceData WHERE seqnumber=1 ) FinalEntranceData INNER JOIN ( SELECT seqnumber,empName,eventdatetime FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY empName,CONVERT(VARCHAR(20),eventdatetime,112) ORDER BY eventdatetime DESC )seqnumber, * FROM #TempData WHERE trnname ='Exit' )ExitData WHERE seqnumber=1 )FinalExitData ON FinalEntranceData.empname =FinalExitData.empname AND CONVERT(VARCHAR(20),FinalEntranceData.eventdatetime,112) = CONVERT(VARCHAR(20),FinalExitData.eventdatetime,112)