我正在使用 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 专家,您将如何解决这个问题(在许多不同的表中查找用户名的特定出现)?
最佳答案
如果您关心一个用户在任何一个表中,而不是多个表中,您有以下选择:
IN
与UNION
:SELECT * FROM players WHERE hashed_email IN ( SELECT username FROM game1 UNION SELECT username FROM game2 UNION SELECT username FROM game3 ... )
IN
与OR
: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) ...
可能还有很多其他选择。您可能应该使用 EXPLAIN
或 EXPLAIN ANALYZE
来找出哪个更有效,但如果所有这三个都产生基本相似的查询计划,我也不会感到惊讶。
请注意,在每个 game*
表中为 username
建立适当的索引当然会有很大帮助。
关于postgresql - SQL : find overlapping cell values across the same column of many tables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41362352/