sql >> Database teknologi >  >> RDS >> PostgreSQL

SQL, hvor joined sæt skal indeholde alle værdier, men kan indeholde flere

Gruppér efter offer.id , ikke efter sports.name (eller 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;

Forudsat den typiske implementering:

  • offer.id og sports.id er defineret som primær nøgle.
  • sports.name er defineret unikt.
  • (sport_id, offer_id) i offers_sports er defineret unik (eller PK).

Du behøver ikke DISTINCT i optællingen. Og count(*) er endnu en smule billigere.

Relateret svar med et arsenal af mulige teknikker:

  • Sådan filtreres SQL-resultater i en har-mange-gennem-relation

Tilføjet af @max (OP) - dette er ovenstående forespørgsel rullet ind i 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


  1. Hovedanvendelse af sys.dm_os_wait_stats

  2. ODP.NET Managed - Kan ikke finde den anmodede .Net Framework Data Provider

  3. Parse filnavn og sti fra fuld sti

  4. Hvordan løser man MySQL-tegnkodningsproblem?