Mysql 5, JOIN + IN(), Verstaendnisproblem
Peter Nack
- datenbank
Guten Morgen allerseits,
ich sitze nun seit geraumer Zeit an einem Select-Statement, welches ich einfach nicht auf die Reihe bekomme.
Folgendes Szenario:
Tabelle "Auto"
Tabelle "Ausstattungen"
(Mapping) Tabelle "Auto_Ausstattungen"
Nun moechte ich alle Autos auslesen, die zb sowohl eine Klimaanlage als auch eine Sitzheizung haben.
Mein SELECT ist stark vereinfacht wie folgt:
SELECT a.id, a.name
FROM autos a
LEFT JOIN ausstattungen AS aus ON a.id = aus.auto_id
Arbeite ich mit der IN()-Anweisung..
mapping.ausstattung_id IN (1,2,3,4)
..so reicht es ja aus, wenn lediglich _eines_ der Ausstattungen zutrifft. Aber nicht alle.
Arbeite ich in der WHERE-Clause zb mit
mapping.ausstattung_id = 4 AND mapping.ausstattung_id = 5
so bekomme ich logishcerweise keine Ergebnisse.
Ich hofffe ich konnte mein Problem verstaendlich genug erlaeutern.
Ein anderer Benutzer hatte das gleiche Problem, und hat dies ein wenig ausfuehrlicher beschrieben.
Ich stehe nach unendlichen Versuchen leider immernoch auf dem Schlauch!
Von daher waere ich fuer jegliche Tips oder Anregungen dankbar!
MfG
Peter
Tach,
ich habe nun zumindest ein funktionierendes Statement.
SELECT DISTINCT
a.id, a.name
FROM
auto a
WHERE EXISTS (
SELECT * FROM Auto_Ausstattung
WHERE Auto_Ausstattung.Auto_Id = a.id
AND Auto_Ausstattung.Ausstattung_Id =1
)
AND EXISTS (
SELECT * FROM Auto_Ausstattung
WHERE Auto_Ausstattung.Auto_Id = a.id
AND Auto_Ausstattung.Ausstattung_Id =2
)
AND EXISTS (
SELECT * FROM Auto_Ausstattung
WHERE Auto_Ausstattung.Auto_Id = a.id
AND Auto_Ausstattung.Ausstattung_Id =3
)
Aber das sieht fuer mich ganz schoen brachial aus. Sprich, was, wenn es sich um ein paar Dutzend Ausstattungen handeln sollte? Dann wird es wohl sicherlich starke Performanceprobleme geben.
MfG
Peter
Hi,
(Mapping) Tabelle "Auto_Ausstattungen"
- Auto_Id
- Ausstattungen_Id
Nun moechte ich alle Autos auslesen, die zb sowohl eine Klimaanlage als auch eine Sitzheizung haben.
Gruppiere die Datensätze der Ausstattungstabelle, deren Ausstattungs-ID Klimaanlage oder Sitzheizung entspricht (WHERE-Klausel), nach der Auto_Id, und verlange, dass die Anzahl der Datensätze in dieser Gruppierung zweien entspricht (HAVING, COUNT()).
MfG ChrisB
Hallo Chris,
danke fuer deinen Beitrag!
Auch wenn ich, zugegeben, von HAVING und GROUP BY nicht gerade viel Ahnung habe, konnte ich mir nun anhand deiner Erklaerung folgendes Statement zusammen basteln:
SELECT DISTINCT
a.name, aus.name
FROM
auto a
LEFT JOIN
auto_ausstattung aa ON a.id = aa.auto_id
LEFT JOIN
ausstattung aus ON aa.ausstattung_id = aus.id
WHERE
aus.id = 1 OR aus.id = 2 OR aus.id = 3
GROUP BY
a.id
HAVING
COUNT(aa.ausstattung_id) = 3
Gibt es hieran etwas auszusetzen oder kann ich das so verwenden?
Die Ergebnisse scheinen korrekt zu sein.
MfG
Peter
Hallo,
anhand der bisherigen Ratschlaege konnte ich das Problem des von mir initial beschriebenen Falles loesen, doch stehe ich nun leider wieder vor einem Problem, an dem ich nicht weiter komme.
Und zwar ist die Situation wie folgt - vergessen wir mal mein bisheriges Beispiel:
Die Datenstruktur ist wie folgt aufgebaut:
Der Benutzer kann die Filteroptionen setzen fuer
a) die Facilities eines Resorts und
b) die Facilities des Rooms einse Resorts
Anwendungsfall:
Ich moechte alle Resorts mit "Loundry Service" und "Car Rental" (resort_facilities), sowie nur Zimmer, welche "Klimaanlage" und "Internet" besitzen (room_facilities).
Lassen wir die RoomFacilities einmal aussen vor, so funktioniert folgendes (vereinfachtes) Statement fuer die ResortFacilities:
SELECT DISTINCT SQL_CALC_FOUND_ROWS
resort.id, resort.name, resort.location_id
FROM
resort
LEFT JOIN
mm_resort_facility ON resort.id = mm_resort_facility.resort_id
LEFT JOIN
resort_facility ON mm_resort_facility.resort_facility_id = resort_facility.id
-- LEFT JOIN
-- room ON resort.id = room.resort_id
-- -- LEFT JOIN
-- -- mm_room_facility ON room.id = mm_room_facility.room_id
-- -- LEFT JOIN
-- -- room_facility ON mm_room_facility.room_facility_id = resort_facility.id
WHERE
( resort_facility.id=1 OR resort_facility.id=2 OR resort_facility.id=3 )
GROUP BY
resort.id
HAVING
COUNT(mm_resort_facility.resort_facility_id) = 3
ORDER BY
votes_overall
DESC LIMIT 0, 4
== Problem 1 ==
Kommentiere ich hingegen jedoch die durch "--" auskommentierten Zeilen wieder ein (nicht die doppelt auskommentierten), so bekomme ich ein falsches Ergebnis (falsch heisst in diesem Kontext, dass nicht alle Resorts korrekt zurueckgegeben werden).
== Problem 2 (Ausbaustufe) ==
Nun kommen die RoomFacilties noch zusaetzlich mit ins Spiel.
Und an dieser Stelle stehe ich derzeit vor einem riesigen Fragezeichen.
Denn an dieser Stelle geht ja das ganze GroupBy und Having-Handling in die Knie. Und der JOIN (unter Problem 1 beschrieben) scheitert ja auch schon.
Was fuer Moeglichkeiten habe ich, meine Anforderungen in einem einzigen Statement unterzubringen?
Gibt es da eine schicke und auch performante Loesung
MfG
Peter, der sehr dankbar waere, wenn einer der SQL-Experten mir hier einen Tip geben koennte.
PS: Ich kann auch gerne noch einen Datenbank-Dump liefern.