我对sql很新,并且已经设置了创建查询的任务,这将为我提供每个用户的第一个也是最后一个入口以及他们在办公室的时间。 到目前为止,我已经得到了以下
SELECT
CONVERT(VARCHAR(10),evts.Eventtime,101) as Date,
CONVERT(VARCHAR(10),evts.Eventtime,108) as Time,
un.UserName AS [User],
case
when p.Name = 'ACU:4321104 - 5th floor (In)' then '5th entrance'
when p.name = 'ACU:4321176 - 4th floor (In)' then '4th entrance'
when p.name = 'ACU:4321176 - 4th floor (Out)' then '4th exit'
when p.name = 'ACU:4321104 - 5th floor (Out)' then '5th exit'
when p.name = 'ACU:4321158 - 3rd Floor (In)' then '3rd entrance'
when p.name = 'ACU:4321158 - 3rd Floor (Out)' then '3rd exit'
end as [where]
FROM
Net2Events.dbo.Events AS evts LEFT OUTER JOIN
dbo.vw_UserNamesFS AS un ON evts.UserID = un.UserID LEFT OUTER JOIN
Net2Events.dbo.[Event subtype description] AS esd ON evts.EventSubType = esd.EventSubType LEFT OUTER JOIN
Net2Events.dbo.[Event description] AS ed ON evts.EventType = ed.EventType LEFT OUTER JOIN
dbo.Peripherals AS p ON evts.Address = p.Address AND evts.SubAddr = p.SubAddr
WHERE evts.EventTime >= dateadd(day,datediff(day,1,GETDATE()),0)
AND evts.EventTime < dateadd(day,datediff(day,0,GETDATE()),0)
可以访问每个入口和出口。任何帮助都将受到高度赞赏。
由于
答案 0 :(得分:1)
如果这不仅仅是一次性报告,您几乎肯定需要调整where
子句,但对于这两个日期之间的所有EventTime
,此查询将为您提供第一个和最后一个每个用户EventTime
以及分钟之间的时间。
如果你需要通过特定的flors进一步解决这个问题,你可以将where
字段重新添加到select
中(虽然我建议不要使用该名称,因为它是一个SQL关键字) }和group by
:
SELECT un.UserName AS [User]
,MIN(evts.Eventtime) as FirstEvent
,MAX(evts.Eventtime) as LastEvent
,DATEDIFF(minute,MIN(evts.Eventtime),MAX(evts.Eventtime)) as TimeDifference
FROM Net2Events.dbo.Events AS evts
LEFT OUTER JOIN dbo.vw_UserNamesFS AS un
ON evts.UserID = un.UserID
LEFT OUTER JOIN Net2Events.dbo.[Event subtype description] AS esd
ON evts.EventSubType = esd.EventSubType
LEFT OUTER JOIN Net2Events.dbo.[Event description] AS ed
ON evts.EventType = ed.EventType
LEFT OUTER JOIN dbo.Peripherals AS p
ON evts.Address = p.Address
AND evts.SubAddr = p.SubAddr
WHERE evts.EventTime >= dateadd(day,datediff(day,1,GETDATE()),0)
AND evts.EventTime < dateadd(day,datediff(day,0,GETDATE()),0)
GROUP BY un.UserName
我认为你需要做的不仅仅是第一个和最后一个事件,因为我认为世界上没有一个100%正确数据的生产数据库。这意味着您需要找到最早的In
事件和最新的Out
事件,然后检查这些事件是否有意义。
您可以从min
和max
这样的聚合中“排除”某些行,并使用case语句替换不可能的值,超出正常范围,如果以后需要,可以处理:
min(case when <criteria to include> then EventTime else '29990101' end)
要将时差格式化为各种日期元素,您需要从最大的日期部分开始 - 即:天?小时? - 然后从那里开始工作。先计算出你有多少个完整的日子,以分钟为单位的值表示整数除以60来得到完整的小时数然后用24来得到完整的天数:
@difference / 60 / 24
然后我们需要整整几个小时的数量,减去整天所占的所有小时数。为此,我们可以使用modulo
代替division
进行上述计算,以查找未创建一整天的剩余小时数:
@difference / 60 % 24
然后要找到剩余的分钟数,我们只需要找到60分的剩余部分:
@difference % 60
做一些cast/convert
以获得正确的格式,并且您在天,小时和分钟方面有所不同:
declare @start datetime = getdate() - 400.255;
declare @end datetime = getdate();
declare @difference int = datediff(minute,@start,@end);
select cast(@difference/60/24 as nvarchar(5)) + case when @difference/60/24 = 1 then ' Day, ' else ' Days, ' end
+ cast(@difference/60%24 as nvarchar(5)) + case when @difference/60%24 = 1 then ' Hour, ' else ' Hours, ' end
+ cast(@difference%60 as nvarchar(5)) + case when @difference%60 = 1 then ' Minute' else ' Minutes' end;
返回:400 Days, 6 Hours, 7 Minutes
当然,如果您只想要hh:mm
格式的小时和分钟,并且非常自信,这个时间差异永远不会超过23小时59分59.9999999秒,您可以简单地将差异转换为时间将值添加到任意日期,并在前端应用程序中进行相应格式化:
cast(dateadd(minute,@difference,0) as time)
对于上述参数,返回06:07:00.0000000
- 请注意缺少的400天。