postgresql - SQL : find overlapping cell values across the same column of many tables

标签 postgresql

我正在使用 postgresql,总的来说,我对 SQL 有点新手。

我正在尝试编写一个查询来检查主列表和多个表之间的值是否重叠。有问题的值是用户名和多个表(总共 30 个),每个表代表不同游戏的事件数据。

每个游戏都有自己的表格,其中的列标题相同。 30 个具有相同列的表,类似这样...:

表名:game1...game30

   USERNAME                                 EVENT_TIMESTAMP       OTHER_FELIDS
   2592761928AF756E45891527ED49A7A9         2016-02-01 02:38:05   ...
   79460FE440ADB429F542D2F08A763D50         2016-02-01 02:38:35   ...
   3945B26DD9F6FD2D49574856ECF9FA7D         2016-02-01 02:44:12   ...
   A597AE2CF6E15497EE7AC2A02CEEB32E         2016-02-01 02:46:57   ...
   65DE308FC39980CCD37DBDE8A432F221         2016-02-01 02:46:57   ...
   ...

我有一个指定的 user_ids 列表,我用它来创建一个“关键表”游戏的事件数据。 我的 key 表只有两列,看起来像这样:

表名:username_key

EMAIL          HASHED_EMAIL
asd0@asd.com   79460FE440ADB429F542D2F08A763D50
asd1@asd.com   0C450FAC330D69A315604CDE61C7A65E
asd2@asd.com   F2D7714CBA1048A940231087549F1D95
bob@asd.com    FE793A075E0633441B5EE5535FAAEDD2
asd7@asd.com   47FAFD07C174B81BADD28AD9BE64E26B
...

(注意:游戏表和 key 表中的用户名都是哈希加密的电子邮件,因此名称为“HASHED_EMAILS”)

我的查询目前看起来像这样:

create temp table players as select ky.hashed_email from username_key as ky 
    inner join game1 g1 on ky.hashed_email = g1.username 
    inner join game2 g2 on ky.hashed_email = g2.username
    inner join game3 g3 on ky.hashed_email = g3.username
    inner join game4 g4 on ky.hashed_email = g4.username
    ...
    inner join game30 g30 on ky.hashed_email = g30.username

当我尝试运行此查询时,它会挂起很长时间...几个小时并最终超时。

我希望返回出现在一个或多个游戏事件表中的用户列表,或者返回一个空列表(这会告诉我关键表列表中没有人玩过游戏)。

我的查询是否在正确的轨道上? 有没有比我现在做的更快/更有效的方法来完成这个任务? 作为 postgresql 专家,您将如何解决这个问题(在许多不同的表中查找用户名的特定出现)?

最佳答案

如果您关心一个用户在任何一个表中,而不是多个表中,您有以下选择:

  • INUNION:

    SELECT * FROM players WHERE hashed_email IN (
        SELECT username FROM game1
        UNION SELECT username FROM game2
        UNION SELECT username FROM game3
        ...
    )
    
  • INOR:

    SELECT * FROM player WHERE hashed_email IN (SELECT username FROM game1)
        OR hashed_email IN (SELECT username FROM game2)
        OR hashed_email IN (SELECT username FROM game3)
        ...
    
  • 存在:

    SELECT * FROM player WHERE EXISTS (SELECT 1 FROM game1 WHERE username=hashed_email)
        OR EXISTS (SELECT 1 FROM game2 WHERE username=hashed_email)
        OR EXISTS (SELECT 1 FROM game3 WHERE username=hashed_email)
        ...
    

可能还有很多其他选择。您可能应该使用 EXPLAINEXPLAIN ANALYZE 来找出哪个更有效,但如果所有这三个都产生基本相似的查询计划,我也不会感到惊讶。

请注意,在每个 game* 表中为 username 建立适当的索引当然会有很大帮助。

关于postgresql - SQL : find overlapping cell values across the same column of many tables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41362352/

相关文章:

django - GitLab CI Django 和 Postgres

sql - 左外连接在 Postgres 中深入两层导致笛卡尔积

java - OpenCSV Reader-Java 的局限性

sql - 如何使用窗口函数优化 SQL 查询

sql - PostgreSQL - 根据 3 列选择重复数据

.net - 在 .NET 中使用 SSH 隧道连接到 postgresql

sql - Golang sql 包查询比 PostgreSQL SQL 查询慢

sql - 一次更新多行

json - 在 postgres 查询中用另一个更新 json 项

postgresql - 如何合并时间戳列?