Heim >Datenbank >MySQL-Tutorial >Wie wähle ich in SQL Angebote aus, die alle Sportarten einer bestimmten Gruppe (aber möglicherweise mehr) enthalten?
SQL: WHERE Joined Set muss alle Werte enthalten, kann aber mehr enthalten
In SQL stellt die Klausel „WHERE JOINED SET“ sicher, dass a Die verknüpfte Tabelle enthält bestimmte Werte in ihrem Ergebnissatz. Die verknüpfte Tabelle kann jedoch auch zusätzliche Werte enthalten, die nicht Teil der Bedingung sind. Dieses Konzept kann in der Praxis schwierig umzusetzen sein, insbesondere wenn es darum geht, zu bestimmen, welche Werte in die Bedingung einbezogen werden sollen.
Betrachten Sie das folgende Beispiel:
Szenario:
Sie haben drei Tabellen: Angebote, Sportarten und Angebote_Sportarten, die Angebote, Sportarten und die Beziehung zwischen ihnen darstellen. Sie möchten Angebote auswählen, die eine bestimmte Reihe von Sportnamen enthalten. Die Angebote müssen alle Sportarten umfassen, können aber auch zusätzliche Sportarten umfassen.
Daten:
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 |
Gewünschtes Ergebnis:
Angesichts des Arrays [„Bodyboarding“, „Surfen“] sollte die Abfrage die Angebote „Medium“ und „Alle“ zurückgeben, da sie beide der angegebenen Elemente enthalten Sport. Das Angebot Light sollte nicht zurückgegeben werden, da es nicht beide Sportarten umfasst.
Falsche Abfrage:
Die folgende Abfrage, die nach Sportnamen gruppiert und sicherstellt, dass genau zwei Sport ist in jedem Angebot enthalten, Rücksendungen Nr Ergebnisse:
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;
Lösung:
Die richtige Abfrage gruppiert nach Angebots-ID statt nach Sportname und prüft die Anzahl der in jedem Angebot enthaltenen unterschiedlichen Sportarten mit 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;
Diese Abfrage gibt die Angebote „Medium“ und „Alle“ zurück, da beide beide der angegebenen Angaben enthalten Sport.
ActiveRecord-Implementierung:
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
Das obige ist der detaillierte Inhalt vonWie wähle ich in SQL Angebote aus, die alle Sportarten einer bestimmten Gruppe (aber möglicherweise mehr) enthalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!