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
Lepaskan: 2025-01-05 07:20:44
asal
951 orang telah melayarinya

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")
Salin selepas log masuk

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;
Salin selepas log masuk

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;
Salin selepas log masuk

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
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan