0

搜索鑑於這些機型:軌道4,活動記錄嚴格的陣列,協會

class Farm < ActiveRecord::Base 
    has_and_belongs_to_many :animals 
end 

Class Animal < ActiveRecord::Base 
    has_and_belongs_to_many :farms 
end 

我需要尋找farmsduckspigscows但沒有catsdogs

這種查詢不起作用:

Animal.joins(:farms) 
.where('animals.name IN ? AND animals.name NOT IN ?', 
good_animal_names, bad_animal_names) 

由於它搜索農場與任何動物。我需要搜索具有所有期望的農場而沒有其他農場的農場。

我也試圖與SQL像這樣的東西:

SELECT farms.id, farms.name 
FROM farms 
INNER JOIN animals_farms ON animals_farms.farm_id = farms.id 
INNER JOIN animals ON animals_farms.animal_id = animals.id 
    WHERE animals.name IN (['ducks', 'pigs', 'cows']) 
    AND animals.name NOT IN (['dogs', 'cats']) 
GROUP BY farms.id, farms.name 
    HAVING COUNT(unique(animals.name)) = 3 

但我不知道,如果animals.name NOT IN真的會排除農場有沒有動物或只養殖場沒有他們中的一個。真正的數據庫很難驗證結果。

此外,能夠在Active Record或Arel中執行查詢應該很棒,但SQL中的任何建議都非常值得歡迎。

數據庫是Oracle,我對Oracle沒有太多的經驗,但是大多數用PostgreSQL的查詢都在這裏工作。

回答

0

嗯,我想我有一個可能的SQL解決方案。請評論,如果你能看到任何問題或知道更好的方法來做到這一點。

WITH included_animals as (SELECT farms.id, farms.name 
    FROM farms 
    INNER JOIN animals_farms ON animals_farms.farm_id = farms.id 
    INNER JOIN animals ON animals_farms.animal_id = animals.id 
    WHERE animals.name IN ('ducks', 'pigs', 'cows') 
    GROUP BY farms.id, farms.name 
    HAVING COUNT(unique(animals.name)) = 3), 
not_included_animals as (SELECT farms.id, farms.name 
    FROM farms 
    INNER JOIN animals_farms ON animals_farms.farm_id = farms.id 
    INNER JOIN animals ON animals_farms.animal_id = animals.id 
    WHERE animals.name IN ('dogs', 'cats') 
    GROUP BY farms.id, farms.name) 
SELECT id, name 
FROM included_animals 
MINUS --use EXCEPT if riding PostgreSQL 
SELECT id, name 
FROM not_included_animals 
0

假設你只有兩類動物 - (好/壞),而你只需要好動物。你可以試試這個嗎?

Farm.joins(:animals).where.not(animals: {name: bad_animal_names})

希望它能幫助!

+0

謝謝,但哪裏是好動物? – 2014-12-19 01:13:04

+0

它會列出除壞動物以外的所有其他動物是什麼意思。請嘗試在您的應用程序中運行 – uday 2014-12-19 01:16:39

+0

第二種方法:'Farm.joins(:animals).where(animals:{name:good_animal_names})' – uday 2014-12-19 02:43:43