我有这样的数据
IP Address | UserName | DateTime |
198.168.1.101 | User 1 | 2019-01-01 9:00:00 |
198.168.1.101 | User 2 | 2019-01-01 9:00:05 |
198.168.1.101 | User 3 | 2019-01-01 9:00:10 |
198.168.1.101 | User 4 | 2019-01-01 9:00:15 |
198.168.1.101 | User 5 | 2019-01-01 10:00:00 |
根据该记录,用户1至4 的登录时间不到300秒。因此,我需要捕获这些数据并通知系统管理员。
我不知道如何在SQL上查询。条件是
使用此脚本,我将获得所有该用户
SELECT UA.*
FROM UserAccess UA join
(SELECT IPAddress
FROM UserAccess
GROUP BY IPAddress
HAVING COUNT(*) > 1
) GUA
on UA.IPAddress = GUA.IPAddress;
我怎么做到的?
答案 0 :(得分:0)
使用自我加入
select distinct A.* FROM t1 a join t1 b
on a.ipaddress=b.ipaddress and b.datetimeval>a.datetimeval
输出:
ipaddress username datetimeval
198.168.1.101 User 1 01/01/2019 09:00:00
198.168.1.101 User 2 01/01/2019 09:00:05
198.168.1.101 User 3 01/01/2019 09:00:10
198.168.1.101 User 4 01/01/2019 09:00:15
答案 1 :(得分:0)
您可以尝试一下。
DECLARE @UserAccess TABLE (IPAddress VARCHAR(16), UserName VARCHAR(20), [DateTime] DATETIME)
INSERT INTO @UserAccess VALUES
('198.168.1.101', 'User 1', '2019-01-01 9:00:00'),
('198.168.1.101', 'User 2', '2019-01-01 9:00:05'),
('198.168.1.101', 'User 3', '2019-01-01 9:00:10'),
('198.168.1.101', 'User 4', '2019-01-01 9:00:15'),
('198.168.1.101', 'User 5', '2019-01-01 10:00:00')
SELECT IPAddress, UserName, [DateTime] FROM @UserAccess U1
CROSS APPLY (SELECT COUNT(*) CNT FROM @UserAccess U2 WHERE
U1.IPAddress = U2.IPAddress
AND ( U2.[DateTime] BETWEEN DATEADD(SECOND,-300, U1.[DateTime])
AND DATEADD(SECOND, 300, U1.[DateTime])) ) X
WHERE X.CNT > 1
结果
IPAddress UserName DateTime
---------------- -------------------- -----------------------
198.168.1.101 User 1 2019-01-01 09:00:00.000
198.168.1.101 User 2 2019-01-01 09:00:05.000
198.168.1.101 User 3 2019-01-01 09:00:10.000
198.168.1.101 User 4 2019-01-01 09:00:15.000
答案 2 :(得分:0)
假设您的表包含列,
IP地址|用户名|日期时间|
并且您需要在300秒之内所有用户,
DECLARE @min_time DATETIME
SELECT @min_time = MIN([DateTime]) FROM UserAccess
SELECT * FROM UserAccess WHERE DATEDIFF(s, @min_time, [DateTime]) <300
答案 3 :(得分:0)
您可以使用窗口功能。 LAG
函数可让您访问上一个行中的一列;您可以使用它来查找以前的日期时间和时差。
WITH cte AS (
SELECT ipaddress
, username
, datetime
, LAG(datetime) OVER (PARTITION BY ipaddress ORDER BY datetime) AS prevdatetime
, LEAD(datetime) OVER (PARTITION BY ipaddress ORDER BY datetime) AS nextdatetime
FROM t
)
SELECT *
FROM cte
WHERE DATEDIFF(second, prevdatetime, datetime) <= 300
OR DATEDIFF(second, datetime, nextdatetime) <= 300
答案 4 :(得分:0)
EXISTS
可能具有良好的性能,并具有正确的索引:
select t.*
from t
where exists (select 1
from t2
where t2.ipaddress = t.ipaddress and
t2.datetime >= dateadd(second, -300, t1.datetime) and
t2.datetime < dateadd(second, 300, t1.datetime)
t2.username <> t.username
);
我猜您希望用户名不同。
您想要的索引位于(ipaddress, datetime, username)
上。