Hallo,
Nun gibt es noch eine Feinheit, die mich zwar nicht sehr stört, aber die ich trotzdem gerne verstehen/beheben würde. Mein Query ist folgender:
das Statement wird nur von MySQL akzeptiert, da Du nicht nach allen Spalten gruppierst, auf die Du keine Aggregatsfunktion anwendest.
SELECT
t.id,
-- im Falle der direkt von t.id abhängigen Spalten ist das kein echtes Problem
-- da die Werte eh' alle die gleichen sind.
t.datum,
t.referenz,
t.preis,
-- für die folgende Spalte bekommst Du selbstverständlich irgendeinen
-- beliebigen möglichen Wert. Bei mehrfachem Ausführen der gleichen Abfrage
-- kann dieser durchaus unterschiedlich sein
tb.id,
GROUP_CONCAT( distinct(b.beschreibung) ) Besonderheiten,
FROM
tour t
LEFT OUTER JOIN
tour_besonderheit tb
ON
t.id = tb.tour_id
LEFT OUTER JOIN
besonderheit b
ON
b.id = tb.besonderheit_id
WHERE t.firma_id = 4
GROUP BY
t.id
ORDER BY
t.id
>
> Wenn ich nun alle Touren mit einer bestimmten Besonderheit anzeigen lassen möchte, erweitere ich die WHERE-Bedingung um ein
> `AND b.id = 4`{:.language-sql}
Nein. Wie Du gemerkt hast, liefert dies nicht das gewünschte Ergebnis. Außerdem gibt's noch ein paar andere Kleinigkeiten :-)
Fangen wir an: Du suchst alle Touren mit einer bestimmten Besonderheit. Daraus folgt, dass Dich Touren \*ohne\* Besonderheit \*nicht\* interessieren. Du weißt, dass die Dich interessierenden Touren mindestens eine Entsprechung in der Tabelle tour\_besonderheit haben. Alle Datensätze der Tabelle tour\_besonderheit haben eine Entsprechung in der Tabelle besonderheiten (das solltest Du über referentielle Integrität sicherstellen :-)
Statt OUTER JOINS kannst Du somit zwei INNER JOINS verwenden, was Die Sache nur schneller machen kann :-)
Wenn es nun nur um eine Besonderheit geht und außerdem gilt, dass die gleiche Besonderheit in der gleichen Tour maximal einmal vorkommen kann (UNIQUE-Index über die Spaltenkombination (tb.tour\_id, tb\_besonderheit\_id), dann kannst Du das Problem mit einem Join erledigen. Allerdings wirst Du sehen, dass diese Lösung nicht flexibel ist und sich nicht leicht erweitern läßt.
~~~sql
SELECT
t.id,
t.datum,
t.referenz,
t.preis,
GROUP_CONCAT( distinct(b.beschreibung) ) Besonderheiten,
FROM
tour t
-- wir joinen ein zweites Mal mit den tour_besonderheiten,
-- um nur die Touren zu erhalten, die die Besonderheit mit der
-- id 4 enthalten.
INNER JOIN
-- wir müssen daher einen anderen Aliasnamen verwenden,
-- als im Join für die Detais
tour_besonderheit tb2
ON
t.id = tb2.tour_id
AND
-- und packen auch die Einschränkung in die Joinbedingung
tb2.besonderheit_id = 4
-- und schauen uns von diesen Touren
-- alle passenden Einträge an
INNER JOIN
tour_besonderheit tb
ON
t.id = tb.tour_id
INNER JOIN
besonderheit b
ON
b.id = tb.besonderheit_id
WHERE
t.firma_id = 4
GROUP BY
t.id
t.datum,
t.referenz,
t.preis
-- in MySQL ist diese ORDER-BY-Klausel überflüssig, da MySQL ohnehin
-- in der Reihenfolge der Spalten der GROUP-BY-Klausel sortiert
ORDER BY
t.id
Dein Problem, wenn zwei verschiedene Besonderheiten erfüllt sein sollen, könntest Du nun mit einem weiteren INNER JOIN auf die zweite gewünschte Besonderheit (und einem dritten Alias) erweitern.
Vom Grundsatz her ist es das gleiche Problem, das asmodin in diesem Archivthread hatte. Schau Dir meine dortigen Vorschläge an und wende sie auf Dein Problem an. Vergiss nicht das Messen mit einer signifikanten Zahl von Datensätzen :-)
Freundliche Grüße
Vinzenz