2017-06-12 108 views
0

我正在使用Amazon Redshift,並且無法獲得正確的查詢。假設我有很多需要一個或多個技能的項目。所以項目和技能之間有多對多的關係。用戶創建項目,所以每個項目有一個創建者。存在多對多關係

對於每個項目,我想通過共享至少一項技能的相同創建者獲得所有其他項目。所以我想寫點東西像這樣:

SELECT p1.project_id, p2.project_id 
FROM projects p1 
JOIN projects p2 on p1.creator = p2.creator 
WHERE EXISTS (SELECT 0 
       from skills sk1, skills sk2 
       where sk1.project_id = p1.project_id 
       and sk2.project_id = p2.project_id 
       and sk1.skill = sk2.skill) 

問題是,這是真的(給出了disk full錯誤)。

下面的作品,但也很慢(需要半小時左右):

SELECT distinct p1.project_id, p2.project_id 
FROM projects p1 
    JOIN projects p2 on p1.creator = p2.creator 
    join skills sk1 on sk1.project_id = p1.project_id 
    join skills sk2 on sk2.project_id = p2.project_id 
WHERE sk1.skill = sk2.skill 

問題與這一個是,如果我想在第二個項目聚集的一些屬性,我必須用它作爲子查詢。

有沒有更好的方法來做到這一點?我會認爲第一個查詢會更快,因爲它停止挑選單個項目。

+0

你有連接列上任何索引設置? –

回答

1

查詢的一個簡單問題是您允許項目自行加入。這意味着每一個項目都會被退回。

修復它通過確保這兩個項目被加入是不一樣的:

JOIN projects p2 on 
    p1.creator = p2.creator and 
    p2.project_id > p1.project_id 

請注意,我用>而不是!=使兩個匹配的項目只在一個方向加入。否則每對項目將返回兩次。然後

您的加入爲基礎的解決辦法是這樣的:

SELECT distinct p1.project_id, p2.project_id 
    FROM projects p1 
    JOIN projects p2 on 
     p1.creator = p2.creator and 
     p2.project_id > p1.project_id 
    join skills sk1 on 
     sk1.project_id = p1.project_id 
    join skills sk2 on 
     sk2.project_id = p2.project_id and 
     sk1.skill = sk2.skill