• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Zuordungstabelle, Abfrage problem

wolf360

Neues Mitglied
Hallo,

ich will eine kleine Homepage mit rezepten erstellen und hab dazu 3 Tabellen erstellt

Gerichte:
gerichte_id,
name,
beschreibung

Zutaten:
zutaten_id,
name

gerichte_x_zutaten:
gerichte_id,
zutaten_id,
menge

So wenn ich jetzt alle Rezepte haben will wo eine der gegebenen Zutaten erhalten soll schaut mein query so aus:

Code:
select * from gerichte g join gerichte_x_zutaten gxz on g.gerichte_id = gxz.gerichte_id where gxz.zutaten_id = 4 or gxz.zutaten_id = 5 group by g.gerichte_id

Damit erhalte ich alle Zutaten die die Zutaten "4" oder die Zutat "5" erhalten.

Meine Frage ist nur, wie erhalte ich alle Gerichte die nur die Zutat 4 UND 5 enthalten?

Grüße

wolf360
 
Werbung:
Hallo
Bin mir grad nicht sicher ob man ALL(..) auf ein having anwenden kann. Falls es aber geht würde ich die Tabellen joinen, nach gericht_id gruppieren und ein having mit all auf eine liste deiner zutaten anwenden..
 
Werbung:
Ich glaub mit having gehts nicht.
Hier sind ein paar Beispiele wie man es realisieren kann query - Finding ID having all values (mySQL, SQL) - Stack Overflow

Ich denke das INTERSECT ist einfach nachzuvollziehen. Du machst 2 SQL Abfragen, in einer überprüfst du, ob Zutat 1 enthalten ist, in der andren prüfst du, ob die andre enthalten ist (selektieren tust du in beiden querys jeweils nur die gericht_id). INTERSECT bildet daraus nun die Schnittmenge, also das, in dem beide drin sind. Den kompletten Query packste dann in folgendes Statement

SELECT distinct name FROM Gerichte WHERE gerichte_id IN (hier kommt das intersect query rein)

distinct killt Duplicate und das IN(..) ist eine kurze Schreibweise für

where xy = 'wert1' or xy = 'wert2' or xy = 'wert3'

IN ('wert1' 'wert2' 'wert3')
 
okey, das heißt ich müsste für jede Zutat folgendes machen:

Code:
SELECT distinct name FROM Gerichte WHERE gerichte_id IN (SELECT gerichte_id FROM gerichte_x_zutaten gxz WHERE gxz.zutaten_id = 2)
AND IN (SELECT gerichte_id FROM gerichte_x_zutaten gxz WHERE gxz.zutaten_id = 5)

Erzeugt das bei mehreren Zutaten aber nicht eine riesen Last wenn ich für jede Zutat einen Subquery erstellen muss?

Grüße

wolf360
 
SELECT gerichte_id FROM gerichte_x_zutaten WHERE zutaten_id in (2,5) GROUP by id HAVING count(*) = 2
ist laut query - Finding ID having all values (mySQL, SQL) - Stack Overflow das schnellste Query und nebenbei scheint es intersect bei mysql nicht zu geben?! Naja wie auch immer. Also so bekommst du deine gerichte_id .. wie du an den Namen kommst wirst du doch noch selbst rausfinden hoffe ich.

Erzeugt das bei mehreren Zutaten aber nicht eine riesen Last wenn ich für jede Zutat einen Subquery erstellen muss?

Um eine SQL DB würde ich mir bei der Größenordnung am allerwenigsten Sorgen machen ;)
 
Werbung:
Wenn dasselbe Feld gleichzeitig den Wert 4 und 5 haben kann, dann ja.
:-) Stimmt, das war Quark

Dann also eher so
Code:
SELECT * FROM 
gerichte g LEFT JOIN gerichte_x_zutaten gxz1 USING(gerichte_id)
 LEFT JOIN gerichte_x_zutaten gxz2 USING(gerichte_id)
where (gxz1.zutaten_id = 4 AND gxz2.zutaten_id = 5) OR (gxz2.zutaten_id = 4 AND gxz1.zutaten_id = 5)

Oder eben den Subselect, die Last sollte gering sein, wenn die Indizes richtig gesetzt sind.
 
Werbung:
danke für die Hilfe =),

ich habe mich jetzt für diese Methode entschiede:

SELECT gerichte_id FROM gerichte_x_zutaten WHERE zutaten_id in (2,5) GROUP by id HAVING count(*) = 2

Grüße

wolf360
 
Zurück
Oben