MySQL 查询以收集比所选 ID 多 X 秒的唯一 ID

MySQL Query to collect unique IDs that are X seconds more than selected ID

我有一个带有用户 ID 和时间戳的 table。我希望收集给定日期(在本例中为 2021-09-03)的不同用户标识。但是,如果用户标识的日期和时间大于 X 秒,那么我也想打印这个用户标识(因为我知道这不是重复的)。

换句话说一个用户进入系统并登录(这是一个真正的登录),但是它可能会在数据库中多次登录,几行重复数据,其中秒或毫秒不同(作为许多遗留系统的结果)。他可能会在 10 秒后(或任何时间范围后)再次登录 - 这是另一个真正的登录(但也可能再次包含几行登录)。因此,我只想显示真实登录的用户 ID 以及日期和时间。

rowid   userid  dateandtime
10      0       2021-09-03 18:48:44.517771
11      0       2021-09-03 18:48:44.873727
12      0       2021-09-03 18:48:44.936010
13      0       2021-09-03 18:48:45.158109
14      0       2021-09-03 18:48:46.385015
15      10      2021-09-03 18:49:00.433325
16      0       2021-09-03 20:03:35.584817
17      0       2021-09-03 20:03:35.633030
18      0       2021-09-03 20:03:36.679559
19      0       2021-09-03 20:03:37.726138
20      4357    2021-09-03 22:41:43.549345
21      4357    2021-09-03 22:41:44.127240
22      4357    2021-09-03 22:41:44.168634
23      4357    2021-09-03 22:41:44.454468

因此您可以看到 userid 0 在 2021-09-03 18:48:44.517771 登录。其他遗留系统继续让他登录几秒和几毫秒(这些是虚假登录)。 然后用户 10 在 2021-09-03 18:49:00.433325 登录,用户 0 在 2021-09-03 20:03:35.584817 再次合法登录(和错误登录),然后是用户 4357 在 2021- 09-03 22:41:43.549345(然后该用户再次错误登录)。

我需要创建一个 MySQL 查询来清除噪音并只得到真实登录的结果:

rowid   userid  dateandtime
10      0       2021-09-03 18:48:44.517771
15      10      2021-09-03 18:49:00.433325
16      0       2021-09-03 20:03:35.584817
20      4357    2021-09-03 22:41:43.549345

给定用户的日期和时间大于 X 秒的不同登录。

谢谢。

我想你可以使用lag()查看以前的用户然后过滤:

select t.*
from (select t.*,
             lag(userid) over (order by dateandtime) as prev_userid
      from t
     ) t
where prev_userid is null or prev_userid <> userid;

您可以使用 TIMESTAMPDIFFLAG 函数将时间(以秒为单位)与同一用户上次登录的时间进行比较。

SET @X = 1; -- X seconds

WITH t1 AS (
  SELECT *,
    TIMESTAMPDIFF(
      second, 
      LAG(dateandtime) OVER (PARTITION BY userid ORDER BY dateandtime), 
      dateandtime
    ) AS seconds
  FROM t
) 
SELECT rowid, userid, dateandtime
FROM t1
WHERE seconds IS NULL OR seconds > @X
ORDER BY dateandtime

db<>fiddle