2015-04-03 224 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不爲空」)