SQL Server:避免重复行的窗口函数
我需要你的帮助,请帮我解决下面的问题。我在SQL Server数据库中有数据,显示用户是否登录了安全系统 数据结构如下所示:SQL Server:避免重复行的窗口函数,sql,sql-server,Sql,Sql Server,我需要你的帮助,请帮我解决下面的问题。我在SQL Server数据库中有数据,显示用户是否登录了安全系统 数据结构如下所示: id SystemId Time PC User Logged ----------------------------------------------- 1 2 20171025 16:01 1 John In 2 2 20171025 17:41 4 Mike In 3
id SystemId Time PC User Logged
-----------------------------------------------
1 2 20171025 16:01 1 John In
2 2 20171025 17:41 4 Mike In
3 2 20171025 17:58 1 John Out
4 2 20171025 17:58 4 Mike Out
5 2 20171025 19:21 4 Peter In
6 2 20171025 21:45 4 Peter In
7 2 20171025 22:59 4 Peter Out
我需要开发一个脚本,每30分钟运行一次,并且必须显示何时没有用户登录安全监控系统
下面的脚本执行此任务,但有系统/网络问题的情况除外,用户被强制注销并再次登录,而数据库中没有记录强制注销。i、 e.第6行中未记录用户注销,而只记录了已登录的用户
这意味着,当我昨天23:30运行脚本检查Peter(在本例中)是否已登录并执行其工作时,结果显示Peter已登录,而实际上他未登录。(见第6行)
我相信我的解决方案是一个窗口函数(分区依据),它跳过列(PC、用户、日志)中具有相同值的任何连续行。这样我就避免了重复计算。但我不知道我的方向是否正确
SELECT
SystemId,
SUM(CASE
WHEN Logged = 'In' THEN 1
WHEN Logged = 'Out' THEN -1
ELSE 0
END) AS Connected
FROM
log.SecurityLogs
GROUP BY
SystemId
HAVING
SUM(CASE
WHEN Logged = 'In' THEN 1
WHEN Logged = 'Out' THEN -1
ELSE 0
END) = 0
用户的状态在
In
和Out
之间变化。根据您的描述,不存在嵌套状态(即,您不会期望In-->In-->Out-->Out)
因此,只需比较最大时间:
select sl.SystemId,
max(case when logged = 'In' then time end) as in_time,
max(case when logged = 'Out' then time end) as out_time
from log.SecurityLogs sl
group by sl.SystemId;
如果您想要最近事件为“in”的人,则:
谢谢林诺夫先生,你又一次救了我。非常感谢您的帮助和时间。你的建议果然奏效了。
select sl.SystemId,
max(case when logged = 'In' then time end) as in_time,
max(case when logged = 'Out' then time end) as out_time
from log.SecurityLogs sl
group by sl.SystemId
having max(case when logged = 'In' then time end) > max(case when logged = 'Out' then time end);