Heim > Datenbank > MySQL-Tutorial > Wie wähle ich in SQL Angebote aus, die alle Sportarten einer bestimmten Gruppe (aber möglicherweise mehr) enthalten?

Wie wähle ich in SQL Angebote aus, die alle Sportarten einer bestimmten Gruppe (aber möglicherweise mehr) enthalten?

Mary-Kate Olsen
Freigeben: 2024-12-27 13:49:10
Original
325 Leute haben es durchsucht

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

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 |
Nach dem Login kopieren

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;
Nach dem Login kopieren

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;
Nach dem Login kopieren

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
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage