SQL门访问

标签 sql sql-server database

我是 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)

它允许访问每个入口和导出。任何帮助将不胜感激。

谢谢

最佳答案

您几乎肯定需要调整您的 where子句,如果这不是一次性报告,但对于所有 EventTime在这两个日期之间,此查询将为您提供第一个和最后一个 EventTime每个用户和他们之间的时间(以分钟为单位)。

如果您需要按特定的花语进一步分割,您可以添加 where字段返回(虽然我不建议使用该名称,因为它是一个 SQL 关键字)到 selectgroup 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事件,然后检查这些是否有意义。

您可以从聚合中“排除”某些行,例如 minmax用一个 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 天。

关于SQL门访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40930211/

相关文章:

sql-server - 在 App_Data 文件夹中使用 sql 数据库发布 mvc 网站

sql-server - Azure 数据工厂复制事件失败。用户登录失败

c# - 如何将数据表动态映射到 SQL 表

java - 结果集元数据不返回第一行

mysql - 聚集索引还是分区表?

sql - 设计——第六范式

sql-server - 使用 FOR XML 选择 xml 格式的数据

sql - 删除sql View 中的重复记录

简单术语的 MySql 字段类型

php - 创建动态页面主体的最有效方法是什么?