Получить пользователей с тем же IP-адресом в течение 300 секунд от SQL - PullRequest
0 голосов
/ 14 марта 2019

У меня есть такие данные

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. Критерии

  1. Тот же IP-адрес
  2. В течение 300 секунд

С помощью этого скрипта я получу всего этого пользователя

SELECT UA.*
FROM UserAccess UA join
     (SELECT IPAddress
      FROM UserAccess
      GROUP BY IPAddress
      HAVING COUNT(*) > 1
     ) GUA
     on UA.IPAddress = GUA.IPAddress;

Как я могу это сделать?

Ответы [ 5 ]

0 голосов
/ 14 марта 2019

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).

0 голосов
/ 14 марта 2019

Вы можете использовать оконные функции.Функция 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

Демо на db <> fiddle

0 голосов
/ 14 марта 2019

Вы можете попробовать это.

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
0 голосов
/ 14 марта 2019

Предполагая, что в вашей таблице есть столбцы, а именно

IP-адрес | Имя пользователя | DateTime |

и вам нужны все пользователи в течение первых 300 секунд,

DECLARE @min_time DATETIME
SELECT @min_time = MIN([DateTime]) FROM UserAccess

SELECT * FROM UserAccess WHERE DATEDIFF(s, @min_time, [DateTime]) <300
0 голосов
/ 14 марта 2019

использовать самостоятельное соединение

DEMO

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...