2017-06-12 98 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