簡體   English   中英

SQL:在許多表的同一列中查找重疊的單元格值

[英]SQL: find overlapping cell values across the same column of many tables

我正在使用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_id列表我正在嘗試編寫一個查詢,告訴我密鑰表列表中的任何用戶是否顯示在游戲的事件數據中。 我的密鑰表只有兩列,看起來像這樣:

表名: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
...

(注意:游戲表和密鑰表中的用戶名都是哈希加密的電子郵件,因此名稱為“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) ... 
  • EXISTS

     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索引當然會有很大幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM