sql >> Databáze >  >> RDS >> PostgreSQL

SQL, kde spojená sada musí obsahovat všechny hodnoty, ale může obsahovat více

Seskupit podle offer.id , nikoli podle sports.name (nebo 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;

Za předpokladu typické implementace:

  • offer.id a sports.id jsou definovány jako primární klíč.
  • sports.name je definován jako jedinečný.
  • (sport_id, offer_id) v offers_sports je definován jako jedinečný (nebo PK).

Nepotřebujete DISTINCT v počtu. A count(*) je ještě o něco levnější.

Související odpověď s arzenálem možných technik:

  • Jak filtrovat výsledky SQL ve vztahu has-many-through

Přidal @max (OP) – toto je výše uvedený dotaz vložený do 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. SQL dotaz pro nalezení záznamu s ID, který není v jiné tabulce

  2. Proč žádný výstup, když se dokončí anonymní blok PLSQL?

  3. MySQL:Více řádků jako jeden řádek oddělený čárkami

  4. .NET Core 2.1 Identity získá všechny uživatele s jejich přidruženými rolemi