我对SQL Server有疑问:如何根据以下条件计算登录和注销时间?
同一名员工可能在同一天多班。注销和登录时间差异超过5小时,然后考虑为该员工的下一班次。
登录和退出时间超过5小时或更短时间,然后仅考虑该员工的相同班次
OnFloor时间花费了多少时间:sum(login time - logout time)
sum(logout time - login time)
示例:emp:101是登录时间:2018-02-06 16:03:08.000,退出时间为:2018-02-06 22:01:40.000则总时间为:5小时:38分钟:32秒
CREATE TABLE [dbo].[empstafflogindetails]
(
[Emp ID] [float] NULL,
[Area Of Access] [nvarchar](255) NULL,
[Time] [datetime] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[empstafflogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N' IN', CAST(N'2017-08-02T09:00:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-02T10:30:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-03T09:30:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-03T12:30:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-03T12:40:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-03T17:10:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-03T06:30:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-03T08:30:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-05T23:30:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-06T01:55:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-06T02:15:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-06T06:10:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-02T11:00:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-02T12:00:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-02T13:00:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-06T14:01:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-06T15:01:00.000' AS DateTime)),
(1, N' IN', CAST(N'2017-08-06T15:20:00.000' AS DateTime)),
(1, N' OUT', CAST(N'2017-08-06T20:01:00.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-05T16:23:49.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-05T16:26:01.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-05T15:20:07.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-05T16:00:07.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-05T16:02:02.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-05T22:41:40.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-05T22:56:33.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-05T22:58:28.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-05T22:58:32.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-05T23:00:28.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-05T21:47:38.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-05T23:28:33.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-06T16:03:08.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-06T22:01:40.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-06T22:42:15.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-07T01:32:08.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-07T00:33:19.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-07T00:33:39.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-07T14:57:57.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-07T22:34:51.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-07T23:05:13.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-07T23:19:57.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-07T23:24:07.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-07T23:31:32.000' AS DateTime)),
(101, N' IN', CAST(N'2018-02-07T23:34:12.000' AS DateTime)),
(101, N' OUT', CAST(N'2018-02-07T23:34:36.000' AS DateTime))
GO
根据以上数据,我想要输出如下:
ShiftDate |ShitStartTime |ShiftEndTime |Total_Time |OnFloor |OffFloor |Emp Id
2017-08-02 |2017-08-02 09:00:00.000 |2017-08-02 12:00:00.000 |04:00:00 |02:30:00 |01:30:00 |1
2017-08-03 |2017-08-03 06:30:00.000 |2017-08-03 17:10:00.000 |10:40:00 |09:30:00 |01:10:00 |1
2017-08-05 |2017-08-05 23:30:00.000 |2017-08-06 06:10:00.000 |06:40:00 |06:20:00 |00:20:00 |1
2017-08-06 |2017-08-06 14:01:00.000 |2017-08-06 20:01:00.000 |06:00:00 |05:41:00 |00:19:00 |1
2018-02-05 |2018-02-05 15:20:07.000 |2018-02-05 23:28:33.000 |08:08:26 |07:06:26 |01:02:00 |101
2018-02-06 |2018-02-06 16:03:08.000 |2018-02-07 01:32:08.000 |09:29:00 |08:20:00 |01:09:00 |101
2018-02-07 |2018-02-07 14:57:57.000 |2018-02-07 23:34:36.000 |08:36:39 |07:59:27 |00:37:12 |101
我试过如下:
select
cast(ShitStartTime as date) ShiftDate, ShitStartTime, ShiftEndTime
, concat(right(concat('0', tTime / 60 / 60 % 24), 2), ':', right(concat('0',tTime/ 60 % 60), 2)
,':',right(concat('0',tTime % 60), 2)) Total_Time
,concat(right(concat('0', onF / 60 / 60 % 24), 2), ':', right(concat('0',onF/ 60 % 60), 2)
,':',right(concat('0',onF % 60), 2))OnFloor
,
concat(right(concat('0', offF / 60 / 60 % 24), 2), ':', right(concat('0',offF/ 60 % 60), 2)
,':',right(concat('0',offF % 60), 2))OffFloor, [Emp Id]
from (
select [Emp Id], isnull( min( case when ltrim( rtrim( [Area Of Access]))='in' then Time end ) ,'1900-01-01')ShitStartTime ,
isnull( max( case when ltrim(rtrim([Area Of Access]))='out'then Time end ) ,'1900-01-01')ShiftEndTime,
sum(iif(ltrim(rtrim([Area Of Access]))='in', diff, 0)) onF
,sum(iif(ltrim(rtrim([Area Of Access]))='out', diff, 0)) offF
, sum(diff) tTime
from (
select *, datediff(SECOND, Time, lead(Time) over (partition by [Emp Id], group_ order by Time)) diff
from (
select
*, sum(gr) over (partition by [Emp Id] order by Time rows unbounded preceding) group_
from (
select
*, iif(datediff(hh, lag(Time) over (partition by [Emp Id] order by Time), Time) <= 5, 0, 1) gr
from
empstafflogindetails
) t
) t
) t
group by [Emp Id], group_
) t order by [Emp ID],ShiftDate
但是这个查询没有返回预期的结果。你能告诉我如何在SQL Server中编写查询来实现这个任务吗?
答案 0 :(得分:0)
检查此查询
select
ShiftDate, ShitStartTime, ShiftEndTime
, Total_Time = right(concat('0', Total_Time / 3600), 2) + ':' + right(concat('0', Total_Time % 3600 / 60), 2) + ':' + right(concat('0', Total_Time % 60), 2)
, OnFloor = right(concat('0', OnFloor / 3600), 2) + ':' + right(concat('0', OnFloor % 3600 / 60), 2) + ':' + right(concat('0', OnFloor % 60), 2)
, OffFloor = right(concat('0', OffFloor / 3600), 2) + ':' + right(concat('0', OffFloor % 3600 / 60), 2) + ':' + right(concat('0', OffFloor % 60), 2)
, [Emp ID]
from (
select
[Emp ID], ShiftDate = cast(min(Time) as date)
, ShitStartTime = min(Time)
, ShiftEndTime = max(Time)
, Total_Time = sum(ss)
, OnFloor = sum(iif(rtrim(ltrim([Area Of Access])) = 'In', ss, 0))
, OffFloor = sum(iif(rtrim(ltrim([Area Of Access])) = 'Out', ss, 0))
from (
select
*, ss = datediff(ss, Time, lead(Time) over (partition by [Emp ID], grp order by Time))
from (
select
*, grp = sum(diff) over (partition by [Emp ID] order by Time)
from (
select
*, diff = iif(datediff(mi, lag(Time) over (partition by [Emp ID] order by Time), Time) > 300 and [Area Of Access] = 'IN', 1, 0)
from
[empstafflogindetails]
) t
) t
) t
group by [Emp ID], grp
) t
输出
ShiftDate ShitStartTime ShiftEndTime Total_Time OnFloor OffFloor [Emp ID]
-------------------------------------------------------------------------------------------------------------------------
2017-08-02 2017-08-02 09:00:00.000 2017-08-02 13:00:00.000 04:00:00 02:30:00 01:30:00 1
2017-08-03 2017-08-03 06:30:00.000 2017-08-03 17:10:00.000 10:40:00 09:30:00 01:10:00 1
2017-08-05 2017-08-05 23:30:00.000 2017-08-06 06:10:00.000 06:40:00 06:20:00 00:20:00 1
2017-08-06 2017-08-06 14:01:00.000 2017-08-06 20:01:00.000 06:00:00 05:41:00 00:19:00 1
2018-02-05 2018-02-05 15:20:07.000 2018-02-05 23:28:33.000 08:08:26 07:06:26 01:02:00 101
2018-02-06 2018-02-06 16:03:08.000 2018-02-07 01:32:08.000 09:29:00 08:48:05 00:40:55 101
2018-02-07 2018-02-07 14:57:57.000 2018-02-07 23:34:36.000 08:36:39 07:59:27 00:37:12 101