mysql - 联合mariadb中的n个表并根据时间戳找到不同的值

标签 mysql sql timestamp distinct

我需要对多个数据库表进行搜索。由于所有表都具有相同的结构(相同的列,它们实际上是同一个表的存档数据),我可以使用 UNION ALL 将它们全部组合起来。

但是,挑战是我需要获取用户名列的不同值,并且对于每个用户名值,我需要在对所有存档数据使用 UNION ALL 后找到最早的时间戳。

我浏览了文档并用 google 搜索了相当长的一段时间,但找不到令人满意的 MySQL 解决方案。

我能想到的唯一方法是编写一些外部代码来使用 UNION ALL 搜索每个用户名的值。并一一运行查询。知道数据库中列出了 100k 个不同的用户名,这将需要相当长的时间。我已经开始这个脚本了,但是感觉效率很低而且浪费资源。

SELECT * FROM table1 WHERE `USERNAME` LIKE 'USERNAMEXXX'
UNION ALL
SELECT * FROM table2 WHERE `USERNAME` LIKE 'USERNAMEXXX'
UNION ALL
SELECT * FROM table3 WHERE `USERNAME` LIKE 'USERNAMEXXX'
UNION ALL
SELECT * FROM table4 WHERE `USERNAME` LIKE 'USERNAMEXXX'
ORDER BY TIME_STAMP ASC
LIMIT 1

上面的 SQL 查询为我提供了每个用户名所需的内容,但我需要为每个不同的用户名迭代它。

补充一下,我还有另一个表,其中包含所有不同的用户名值。我使用该表来填充对我的外部代码解决方案的搜索。

有没有办法使用 native SQL 来实现此目的,而无需外部脚本?结合了不同、联合所有和按时间戳 asc 限制 1 排序的东西。

最佳答案

在 MySQL 8+ 中,您可以使用窗口函数:

SELECT t.*
FROM (SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY username ORDER BY timestamp) as seqnum
      FROM ((SELECT t.* FROM table1 t) UNION ALL
            (SELECT t.* FROM table2 t) UNION ALL
            (SELECT t.* FROM table3 t) UNION ALL
            (SELECT t.* FROM table4 t)
           ) t
     ) t
WHERE seqnum = 1;

在早期版本中,您可以使用变量:

SELECT t.*
FROM (SELECT t.*,
             (@rn := IF(@u = username, @rn + 1,
                        IF(@u := username, 1, 1)
                       )
             ) as seqnum
             ROW_NUMBER() OVER (PARTITION BY username ORDER BY timestamp) as seqnum
      FROM ((SELECT t.* FROM table1 t) UNION ALL
            (SELECT t.* FROM table2 t) UNION ALL
            (SELECT t.* FROM table3 t) UNION ALL
            (SELECT t.* FROM table4 t)
            ORDER BY username, timestamp
           ) t CROSS JOIN
           (SELECT @u := '', @rn := 0) params
     ) t
WHERE seqnum = 1;

上面假设您需要所有列。如果您只想要最小时间戳和用户名,请使用聚合:

SELECT username, MIN(timestamp),
FROM ((SELECT t.* FROM table1 t) UNION ALL
      (SELECT t.* FROM table2 t) UNION ALL
      (SELECT t.* FROM table3 t) UNION ALL
      (SELECT t.* FROM table4 t)
     ) t
GROUP BY username;

关于mysql - 联合mariadb中的n个表并根据时间戳找到不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56215737/

相关文章:

java - 在Java中获取最大值sql

sql - 使用SQL获取未知字符串的模式?

PHP MySQL : problems with comparing timestamps in millis

php - 使用数据库中的值进行动态邮件配置 [Laravel]

php - CDbCriteria 和 mysql 使用 INDEX()

php - 合并来自两个不同数据集的数据(Facebook 和 MySQL)

javascript - 使用表单提交操作传递 $_GET 变量

php - 切换数据库mysql中的所有二进制值

python - 在 Python 中删除旧目录

mysql - SQL select true if 日期比较