offer.id
でグループ化 、sports.name
ではありません (またはsports.id
):
SELECT o.*
FROM sports s
JOIN offers_sports os ON os.sport_id = s.id
JOIN offers o ON os.offer_id = o.id
WHERE s.name IN ('Bodyboarding', 'Surfing')
GROUP BY o.id -- !!
HAVING count(*) = 2;
典型的な実装を想定しています:
-
offer.id
およびsports.id
主キーとして定義されています。 -
sports.name
一意に定義されています。 -
(sport_id, offer_id)
offers_sports
で 一意(またはPK)と定義されています。
DISTINCT
は必要ありません カウントで。そしてcount(*)
まだ少し安いです。
可能な技術の武器との関連する答え:
- SQLの結果をフィルタリングしてhas-many-through関係にする方法
@max(OP)によって追加されました-これはActiveRecordにロールインされた上記のクエリです:
class Offer < ActiveRecord::Base
has_and_belongs_to_many :sports
def self.includes_sports(*sport_names)
joins(:sports)
.where(sports: { name: sport_names })
.group('offers.id')
.having("count(*) = ?", sport_names.size)
end
end