2015-04-03 53 views
0

我正在一个查询,正在推动我坚果。我正在尝试通过连接表中的值来搜索表。目前,该查询正在返回具有任一指定ID的所有结果。我只想要它返回只有两个ID的记录。Postgresql INNER JOIN与多个条件

这里是我的表设置

creat_table champions do |t| 
    t.integer :id 
end 

create_table champions_champion_combinations do |t| 
    t.integer :champion_id 
    t.integer :champion_combination_id 
end 

create_table champion_combinations do |t| 
    t.integer :id 
end 

下面是该查询我有它

SELECT 
    champion_combinations.* 
FROM champion_combinations 
INNER JOIN champions_champion_combinations 
    ON champions_champion_combinations.champion_combination_id = champion_combinations.id 
INNER JOIN champions 
    ON champions.id = champions_champion_combinations.champion_id 
WHERE champions.id IN (1, 2)" 

从RoR的ActiveRecord的查询生成

ChampionCombination.joins(:champions).where(champions: {id:[1,2]}) 

因此,这将返回所有champion_combinations那要么加入冠军id 1或2。我需要写什么类型的查询,只返回组合了ID和ID 2的组合?

在此先感谢。

+0

你可以做两个单独的连接到'冠军'表。第一个id是一个,第二个id是一个。 – 2015-04-03 19:42:01

回答

2

如果您在纯SQL解决方案中很有趣,那么您可以使用GROUP BYHAVING子句来实现您的目标。这里是SQL查询:

SELECT cc.* 
FROM champion_combinations AS cc 
INNER JOIN champions_champion_combinations AS ccc ON ccc.champion_combination_id = cc.id 
WHERE ccc.champion_id IN (1, 2) 
GROUP BY cc.id 
HAVING array_agg(ccc.champion_id) @> ARRAY[1,2]; 

PS感谢@IgorRomanchenko伟大的建议。

+0

你不需要冠军表。您可以安全地使用'ccc.champion_id'而不是'c.id'。 – 2015-04-03 19:43:41

+0

@IgorRomanchenko是的,你是对的!谢谢。我已经更新了答案。 – alexpods 2015-04-03 19:44:16

+1

你应该添加额外的条件'WHERE ccc.champion_id IN(1,2)'。否则,postgres将被迫执行完整的扫描和连接,而不是索引连接。 – 2015-04-03 19:45:03

1

这不是内连接问题。内部连接按预期工作。上面给出的SQL查询用“champion_combination”进行两个表的内部连接,但没有限制,表示两个id都必须存在。你应该做的是

ChampionCombination.joins(:冠军)。凡(冠军:{ID:[1,2]})。其中( “champion_id不是null compion_combination_id不为空”)