Rumah > pangkalan data > tutorial mysql > Bagaimana untuk Memilih Tawaran yang Mengandungi Semua Set Sukan (Tetapi Mungkin Lebih Banyak) dalam SQL?

Bagaimana untuk Memilih Tawaran yang Mengandungi Semua Set Sukan (Tetapi Mungkin Lebih Banyak) dalam SQL?

Mary-Kate Olsen
Lepaskan: 2024-12-27 13:49:10
asal
325 orang telah melayarinya

How to Select Offers Containing All of a Given Set of Sports (But Possibly More) in SQL?

SQL: WHERE Set Yang Dicantumkan Mesti Mengandungi Semua Nilai Tetapi Mungkin Mengandungi Lebih Banyak

Dalam SQL, klausa "WHERE JOIND SET" memastikan bahawa jadual bercantum termasuk nilai khusus dalam set hasilnya. Walau bagaimanapun, jadual yang dicantumkan juga mungkin termasuk nilai tambahan yang bukan sebahagian daripada syarat. Konsep ini boleh menjadi mencabar untuk dilaksanakan dalam amalan, terutamanya apabila menentukan nilai yang perlu disertakan dalam keadaan.

Pertimbangkan contoh berikut:

Senario:

Anda mempunyai tiga jadual: tawaran, sukan dan tawaran_sukan, yang mewakili tawaran, sukan dan hubungan antara mereka. Anda ingin memilih tawaran yang termasuk pelbagai nama sukan yang diberikan. Tawaran mesti mengandungi semua sukan tetapi mungkin juga termasuk sukan tambahan.

Data:

offers
| id | name |
| --- | ---- |
| 1 | light |
| 2 | medium |
| 3 | all |
| 4 | extreme |

sports
| id | name |
| --- | ---- |
| 1 | Yoga |
| 2 | Bodyboarding |
| 3 | Surfing |
| 4 | Parasailing |
| 5 | Skydiving |

offers_sports
| offer_id | sport_id |
| --- | ---- |
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |
| 3 | 5 |
| 4 | 3 |
| 4 | 4 |
| 4 | 5 |
Salin selepas log masuk

Keputusan yang Diingini:

Memandangkan tatasusunan ["Bodyboarding", "Melayari"], pertanyaan harus mengembalikan medium tawaran dan semua kerana ia mengandungi kedua-dua sukan tertentu. Lampu tawaran tidak boleh dikembalikan kerana ia tidak termasuk kedua-dua sukan.

Pertanyaan Salah:

Pertanyaan berikut, yang mengumpulkan mengikut nama sukan dan memastikan betul-betul dua sukan termasuk dalam setiap tawaran, pulangan no keputusan:

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

Penyelesaian:

Kumpulan pertanyaan yang betul mengikut ID tawaran dan bukannya nama sukan dan menyemak kiraan sukan berbeza yang disertakan dalam setiap tawaran menggunakan COUNT( DISTINCT):

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

Pertanyaan ini akan mengembalikan medium tawaran dan kesemuanya kerana kedua-duanya termasuk kedua-dua yang ditentukan sukan.

Pelaksanaan 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(DISTINCT sports.name) = ?", sport_names.size)
  end
end
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimana untuk Memilih Tawaran yang Mengandungi Semua Set Sukan (Tetapi Mungkin Lebih Banyak) dalam SQL?. 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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan