Rumah >pangkalan data >tutorial mysql >Bagaimana untuk Membuat Pertanyaan untuk Tawaran yang Mengandungi Set Sukan Tertentu dalam Hubungan Ramai-ke-Ramai?

Bagaimana untuk Membuat Pertanyaan untuk Tawaran yang Mengandungi Set Sukan Tertentu dalam Hubungan Ramai-ke-Ramai?

DDD
DDDasal
2025-01-05 07:20:44960semak imbas

How to Query for Offers Containing a Specific Set of Sports in a Many-to-Many Relationship?

Ralat SQL: "di mana set gabungan mesti mengandungi semua nilai tetapi mungkin mengandungi lebih banyak" untuk Tawaran dan Penapis Sukan

Dalam pangkalan data kami, kami mempunyai tiga jadual: tawaran, sukan, dan jadual sertai menawarkan_sukan. Kami ingin mendapatkan semula tawaran yang termasuk set sukan tertentu, dengan syarat bahawa semua sukan tertentu mesti ada, tetapi sukan tambahan juga boleh disertakan.

Sebagai contoh, mempertimbangkan tawaran berikut:

  • Cahaya: Yoga, Bodyboarding
  • Medium: Yoga, Bodyboarding, Selancar
  • Semua: Yoga, Papan Badan, Selancar, Parasailing, Terjun Melayang

Jika kami meminta tawaran yang mengandungi "Bodyboarding" dan "Selancar", kami mengharapkan untuk menerima kedua-dua "Sederhana" dan "Semua" tetapi bukan "Cahaya." Walau bagaimanapun, pertanyaan semasa kami:

Offer.joins(:sports)
     .where(sports: { name: ["Bodyboarding", "Surfing"] })
     .group("sports.name")
     .having("COUNT(distinct sports.name) = 2")

Dan yang setara dengan SQL:

SELECT "offers".* 
FROM "offers" 
INNER JOIN "offers_sports" ON "offers_sports"."offer_id" = "offers"."id"     
INNER JOIN "sports" ON "sports"."id" = "offers_sports"."sport_id" 
  WHERE "sports"."name" IN ('Bodyboarding', 'Surfing') 
GROUP BY sports.name 
HAVING COUNT(distinct sports.name) = 2;

Tiada pulangan hasil.

Untuk membetulkannya, kami mengubah suai pertanyaan kami kepada kumpulan mengikut ID tawaran dan bukannya nama sukan:

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;

atau 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

Pengubahsuaian ini memastikan kami mengumpulkan hasil dengan sewajarnya dan menggunakan kriteria penapisan yang diperlukan untuk mendapatkan semula tawaran yang diingini termasuk sukan yang dinyatakan.

Atas ialah kandungan terperinci Bagaimana untuk Membuat Pertanyaan untuk Tawaran yang Mengandungi Set Sukan Tertentu dalam Hubungan Ramai-ke-Ramai?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn