PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

SQL di mana set yang digabungkan harus berisi semua nilai tetapi mungkin berisi lebih banyak

Kelompokkan menurut offer.id , bukan dengan sports.name (atau 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;

Dengan asumsi implementasi tipikal:

  • offer.id dan sports.id didefinisikan sebagai kunci utama.
  • sports.name didefinisikan unik.
  • (sport_id, offer_id) di offers_sports didefinisikan unik (atau PK).

Anda tidak perlu DISTINCT dalam hitungan. Dan count(*) bahkan sedikit lebih murah.

Jawaban terkait dengan gudang teknik yang memungkinkan:

  • Cara memfilter hasil SQL dalam relasi has-many-through

Ditambahkan oleh @max (OP) - ini adalah kueri di atas yang dimasukkan ke dalam 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL SELECT kecepatan int vs varchar

  2. Mengubah Database pengembangan Django dari SQLite default ke PostgreSQL

  3. Beberapa CTE dalam satu permintaan

  4. Memanggil fungsi atau prosedur yang tersimpan tidak akan memasukkan dan mempertahankan perubahan

  5. Inti Kerangka Entitas - Berisi apakah peka huruf besar-kecil atau tidak peka huruf besar-kecil?