我对SQL Server有疑问。请告诉我如何根据条件解决SQL Server中的登录和注销时间计算。
empid
可以多班次,同一日期的多班次计算必须是时差为5小时,然后该日期视为该emp的多班次示例输入数据:
CREATE TABLE [dbo].[emplogindetails]
(
[Emp ID] [float] NULL,
[Area Of Access] [nvarchar](255) NULL,
[Time] [datetime] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-02T09:00:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-02T10:30:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-03T09:30:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-03T12:30:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-03T12:40:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-03T17:10:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-03T06:30:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-03T08:30:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-05T23:30:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-06T01:55:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-06T02:15:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-06T06:10:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-02T11:00:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-02T12:00:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-02T13:00:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-06T14:01:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-06T15:01:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4F White Rm IN', CAST(N'2017-08-06T15:20:00.000' AS DateTime))
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time])
VALUES (1, N'K4FWhite Rm OUT', CAST(N'2017-08-06T20:01:00.000' AS DateTime))
GO
根据以上数据,第4个日期是假日,他进入第5个日期夜班,退出第6个日期和第6个日期,他又做了另一个班次。
我想要一个如下输出:
ShiftDate |ShitStartTime |ShiftEndTime |Total_Time |OnFloor |OffFloor |EmpID |Incount |OutCount |Tailgate
08/05/2017 |2017-08-05 23:30:00.000 |2017-08-06 06:10:00.000 |6:40:00 |06:00:00 |00:40:00 |1 |2 | 2 | 0
08/02/2017 |2017-08-02 09:00:00.000 |2017-08-02 13:00:00.000 |04:00:00 |02:30:00 |01:30:00 |1 |3 | 2 | 1
08/03/2017 |2017-08-03 06:30:00.000 |2017-08-03 17:10:00.000 |10:40:00 |09:30:00 |01:10:00 |1 |3 | 3 | 0
08/06/2017 |2017-08-06 14:01:00.000 |2017-08-06 20:01:00.000 |6:00:00 |05:10:00 |00:50:00 |1 |2 | 2 | 0
我试过这样:
select
isnull( ShiftDate ,'1900-01-01')as ShiftDate ,
isnull( min(logintime) ,'1900-01-01') as ShitStartTime,
max( case when logouttime is null then '1900-01-01' else logouttime end )ShiftEndTime ,
convert(varchar(8),dateadd(ss,sum(datediff(second,0,dateadd(day,0,Total_Time))),0),108) Total_Time,
convert(varchar(8),dateadd(ss,sum(datediff(second,0,dateadd(day,0,OnFloor))),0),108) OnFloor,
convert(varchar(8),dateadd(ss,sum(datediff(second,0,dateadd(day,0,OffFloor))),0),108) OffFloor,
EmpID ,Incount ,OutCount, Tailgate
from (
select
CONVERT(VARCHAR(12), ( OffFloor + cast ( OnFloor as int)) / 60 / 60 % 24)
+':'+ CONVERT(VARCHAR(2), (OffFloor + cast ( OnFloor as int)) / 60 % 60)
+':'+ CONVERT(VARCHAR(2), (OffFloor + cast ( OnFloor as int)) % 60) as Total_Time
,case when convert( varchar(10),OnFloor )='0' then '0:0:0' else OnFloor end OnFloor
, CONVERT(VARCHAR(12), (OffFloor) / 60 / 60 % 24) +':'+ CONVERT(VARCHAR(2), (OffFloor) / 60 % 60)
+':'+ CONVERT(VARCHAR(2), (OffFloor) % 60) AS OffFloor
,[Emp ID] ,[Area Of Access],status,logintime,logouttime
from (
select isnull( DATEDIFF(SECOND, a.logintime, a.logouttime) ,0) OffFloor , cast ( '0' as varchar) as OnFloor
,[Emp ID] ,[Area Of Access],status,logintime,logouttime
from (
SELECT o.time logouttime,i.Time logintime,i.[Emp ID]
,substring ( i.[Area Of Access] ,charindex('out',i.[Area Of Access]),len(i.[Area Of Access])) status
,i.[Area Of Access]
FROM test.dbo.emplogindetails i left join test.dbo.emplogindetails o
on i.[emp id] = o.[emp id]
AND CONVERT(date, i.time) = CONVERT(date, o.time)
AND o.time > i.time
AND substring ( o.[Area Of Access] ,charindex('in',o.[Area Of Access]),len(o.[Area Of Access]))='in'
and substring ( i.[Area Of Access] ,charindex('out',i.[Area Of Access]),len(i.[Area Of Access]))='out'
and o.Time=(SELECT MIN(o2.time)
FROM test.dbo.emplogindetails o2
WHERE o2.time > i.time
and o2.[Emp ID]=i.[Emp ID]
---and [emp id]='105828'
)
--where i.[emp id]='105828'
)a where a.status='out')a
union all
select CONVERT(VARCHAR(12), (OffFloor + OnFloor) / 60 / 60 % 24)
+':'+ CONVERT(VARCHAR(2), (OffFloor + OnFloor) / 60 % 60)
+':'+ CONVERT(VARCHAR(2), (OffFloor + OnFloor) % 60) as Calculated_Time
, CONVERT(VARCHAR(12), (OnFloor) / 60 / 60 % 24)
+':'+ CONVERT(VARCHAR(2), (OnFloor) / 60 % 60)+':'+ CONVERT(VARCHAR(2), (OnFloor) % 60) AS OnFloor
, case when convert( varchar(10),OffFloor) ='0' then '0:0:0' else OffFloor end OffFloor
,[Emp ID] ,[Area Of Access],
status,logintime,logouttime
from (
select '0' as OffFloor, isnull( DATEDIFF(SECOND, a.logintime, a.logouttime) ,0) OnFloor
,[Emp ID] ,[Area Of Access],status
,logintime,logouttime
from (
SELECT o.time logouttime,i.Time logintime,i.[Emp ID]
,substring ( i.[Area Of Access] ,charindex('in',i.[Area Of Access]),len(i.[Area Of Access])) status
,i.[Area Of Access]
FROM test.dbo.emplogindetails i left join test.dbo.emplogindetails o
on i.[emp id] = o.[emp id]
AND CONVERT(date, i.time) = CONVERT(date, o.time)
AND o.time > i.time
AND substring ( o.[Area Of Access] ,charindex('out',o.[Area Of Access]),len(o.[Area Of Access]))='out'
and substring ( i.[Area Of Access] ,charindex('in',i.[Area Of Access]),len(i.[Area Of Access]))='in'
and o.Time=(SELECT MIN(o2.time)
FROM test.dbo.emplogindetails o2
WHERE o2.time > i.time
and o2.[Emp ID]=i.[Emp ID]
---and [emp id]='105828'
)
---where i.[emp id]='105828'
)a where a.status='in')stag)stag
join
----get incount and outcount and tailgate information
(select [emp id]as empid,incount,outcount,
isnull( incount-outcount ,0) as Tailgate ,Date as ShiftDate
from (
select
i.[Emp ID] ,convert(varchar(10),time,101) as Date,
count( case when substring ( i.[Area Of Access] ,charindex('in',i.[Area Of Access]),len(i.[Area Of Access]))='in'
then 'in' end )Incount
,count( case when substring ( i.[Area Of Access] ,charindex('out',i.[Area Of Access]),len(i.[Area Of Access]))='out'
then 'out' end )outcount
FROM test.dbo.emplogindetails i
--where [emp id]='105828'
group by i.[Emp ID],convert(varchar(10),time,101)
)cnt)cnt
on stag.[Emp ID]=cnt.empid and convert(varchar(10),stag.logintime,101)=cnt.ShiftDate
group by EmpID ,Incount ,OutCount, Tailgate
,isnull( ShiftDate ,'1900-01-01')
如果退出和登录时间差超过5小时,那么当同一日期有多个班次计算时,此查询不返回预期结果,则视为下一班次。 按照以下给出的逻辑不适用于empid = 5和数据如下所示。 嗨,根据我们的逻辑,一条记录失败。逻辑中需要进行一些更改。以下示例我没有得到预期的输出。
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time]) VALUES (5, N'K4F White Rm IN', CAST(N'2017-08-02T23:30:00.000' AS DateTime))
GO
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time]) VALUES (5, N' K4FWhite Rm OUT', CAST(N'2017-08-03T01:30:00.000' AS DateTime))
GO
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time]) VALUES (5, N'K4F White Rm IN', CAST(N'2017-08-03T01:40:00.000' AS DateTime))
GO
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time]) VALUES (5, N'K4F White Rm OUT', CAST(N'2017-08-03T04:00:00.000' AS DateTime))
GO
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time]) VALUES (5, N'K4F White Rm IN', CAST(N'2017-08-03T04:30:00.000' AS DateTime))
GO
INSERT [dbo].[emplogindetails] ([Emp ID], [Area Of Access], [Time]) VALUES (5, N'K4F White Rm OUT', CAST(N'2017-08-03T06:00:00.000' AS DateTime))
GO
请告诉我如何在SQL Server中完成此任务
答案 0 :(得分:0)
此查询返回您的预期输出
list2