SQL-Brett vorm Kopf ...
Ulf
- datenbank
0 MrWurf0 Webtauschen1 Sven Rautenberg0 fanelf.de
Hi Forum,
hab grad dickes Brett vorm Kopf und komm nicht auf eine bestimmt total banale SQL-Query:
Hab eine Tabelle der Form "rezepte_zutaten"
mit rezept_id und zutat_id.
In einer Abfrage kann man nun seine vorhandenen Zutaten ankreuzen und es sollen alle Rezepte ausgespuckt werden die darauf passen.
Ich hab momentan folgndes (mit PHP):
$query = "SELECT rezept_id FROM rezepte_zutaten WHERE zutat_id IN (".join($zutaten_ids, ',').")";
Damit bekomm ich aber alle Rezepte die mindestens eine der Zutaten haben und nicht die deren Zutatenliste komplett in der Menge der übergebenen Zutaten-Ids enthalten ist... ?!
Grüße, Ulf
Hiho
Ich hab momentan folgndes (mit PHP):
$query = "SELECT rezept_id FROM rezepte_zutaten WHERE zutat_id IN (".join($zutaten_ids, ',').")";
es soll DB-Experten geben, die kein PHP können. Nur so am Rande...
Damit bekomm ich aber alle Rezepte die mindestens eine der Zutaten haben und nicht die deren Zutatenliste komplett in der Menge der übergebenen Zutaten-Ids enthalten ist... ?!
scheint mir auch sinnvoll so, aber wenn du es andersrum willst:
mit
SELECT rezept_id FROM rezepte_zutaten WHERE zutat_id NOT IN (zutat1, zutat2 ...)
erhältst du eine Liste der rezept_id, wo eine Zutat fehlt.
Der Rest sollte auch mit Brett vorm Kopf leicht sein.
Gruß
Wurf
Hi Forum,
hab grad dickes Brett vorm Kopf und komm nicht auf eine bestimmt total banale SQL-Query:
Hab eine Tabelle der Form "rezepte_zutaten"
mit rezept_id und zutat_id.
In einer Abfrage kann man nun seine vorhandenen Zutaten ankreuzen und es sollen alle Rezepte ausgespuckt werden die darauf passen.
Ich hab momentan folgndes (mit PHP):
$query = "SELECT rezept_id FROM rezepte_zutaten WHERE zutat_id IN (".join($zutaten_ids, ',').")";
Damit bekomm ich aber alle Rezepte die mindestens eine der Zutaten haben und nicht die deren Zutatenliste komplett in der Menge der übergebenen Zutaten-Ids enthalten ist... ?!Grüße, Ulf
Lieber Ulf,
da mir heute morgen so nett geholfen wurde, will ich mich mal versuchen ;-)))
Ich denke der Fehler liegt darin dass Du nach ODER und nicht nach UND suchst???
Suche ich ein Rezept zu Mehl, Eier kriege ich Pudding, Pfannkuchen etc.
Suche ich aber nur nach Mehl UND Eiern UND nach 2 Zutaten, dann müsste es klappen!
Am besten ein weiteres Datenbankfeld hinzufügen mit der Anzahl Zutaten...
Dann im Vorfeld die Anzahl der zu suchenden Zutaten (SELECT COUNT(zutat_id) AS Anzahl_ID...) ermitteln und danach die Abfrage
SELECT rezept_id FROM rezepte..... WHERE.... AND...
Ist vielleicht Quatsch aber müsste funzen ;-))))
Liebe Grüße, Claudi...
Moin!
hab grad dickes Brett vorm Kopf und komm nicht auf eine bestimmt total banale SQL-Query:
Nein, die Aufgabenstellung ist alles andere als banal.
Hab eine Tabelle der Form "rezepte_zutaten"
mit rezept_id und zutat_id.
Mit anderen Worten:
Rezepte:
Rührei = 1
Pfannkuchen = 2
Frühstücksei = 3
Zutaten:
Eier = 1
Mehl = 2
Milch = 3
Und verknüpft:
rezept_id zutat_id
1 1
2 1
2 2
1 3
2 3
3 1
Mit anderen Worten: Rührei besteht aus Eiern und Milch, und Pfannkuchen aus Eiern, Mehl und Milch. Das Frühstücksei besteht nur aus Eiern.
Die Frage ist jetzt, was du die Datenbank fragen willst:
Mit der Frage "Was enthält neben anderem Zeugs auch Eier oder Milch" bist du bei deinem jetzigen Query. Da kommen dann allerdings alle drei Rezepte bei heraus.
Alternative Fragemöglichkeiten sind:
"Was enthält mindestens genau die Zutaten, aber ggf. auch noch mehr?"
Die Antwort bei "Eiern, Milch" wäre dann Rührei (enthält Eier und Milch) sowie Pfannkuchen (enthält Eier, Milch, und zusätzlich noch Mehl).
"Was enthält exakt die angegebenen Zutaten?"
Einzige Antwort bei "Eiern, Milch" wäre dann das Rührei.
Ich hab momentan folgndes (mit PHP):
$query = "SELECT rezept_id FROM rezepte_zutaten WHERE zutat_id IN (".join($zutaten_ids, ',').")";
Damit bekomm ich aber alle Rezepte die mindestens eine der Zutaten haben und nicht die deren Zutatenliste komplett in der Menge der übergebenen Zutaten-Ids enthalten ist... ?!
Insbesondere bekommst du mit dieser Abfrage jedes Rezept, welches mehr als eine der gewünschten Zutaten hat, mehrfach in deiner SQL-Ergebnisliste aufgeführt.
Aber genau diesen Effekt kannst du dir zunutze machen:
SELECT rezept_id, count(rezept_id) as zutatentreffer FROM rezepte_zutaten WHERE zutat_ID IN (1,2) GROUP BY rezept_id HAVING zutatentreffer = 2;
Du hast zwei Zutaten, fragst also nach allen Rezepten, die zwei Zutaten "richtig" haben.
Damit kriegst du dann alle Rezepte, die MINDESTENS die geforderten Zutaten enthalten.
Die Frage nach Rezepten, die EXAKT die geforderten Zutaten enthalten, müßte man prüfen, ob die gefundenen Mindest-Rezepte keine weiteren Zutateneinträge besitzen. Ggf. mit einem Subselect (bei MySQL versionsabhängig erst ab 4.1 verfügbar, IIRC).
- Sven Rautenberg
hab grad dickes Brett vorm Kopf und komm nicht auf eine bestimmt total banale SQL-Query:
so ist es
Damit bekomm ich aber alle Rezepte die mindestens eine der Zutaten haben und nicht die deren Zutatenliste komplett in der Menge der übergebenen Zutaten-Ids enthalten ist... ?!
du benötigst eine UND bedingung, welche sich über mehrere zeilen erstreckt. diese frage wird zwar alle nase lang gestellt, aber ist wohl immer je nach aufgabenformulierung verwirrend.
eine UND bedingung über mehrere zeilen wird üblicherweise mit einem self-join erledigt.
SELECT spalten
FROM tabelle t1 INNER JOIN tabelle t2 USING(spalte)
WHERE spalte IN(wert1, wert2 ...)
für deine anforderung mußt du USING(rezept_id) einsetzen und in der WHERE klausel die zutaten.
nachschlag: sorry, so ist es, wenn man über aufgaben solcher art nicht mehr nachdenkt.
UND war gefragt. hier muß jedes UND einen SELF-join haben
antwort:
SELECT rezept
FROM tabelle t1 INNER JOIN tabelle t2 USING(rezept) INNER JOIN tabelle t3 USING(rezept) ...
WHERE t1.zutat1 = wert1 AND t2.zutat2 = wert2 AND t3.zutat3 = wert3 ...
du mußt je nach anzahl zutaten einen entsprechend langen join zusammen basteln
eine alternative bestünde tatsächlich darin, mit COUNT über die rezepte zu gruppieren und die anzahl mit der anzahl der zutaten aus der bedingung zu verbinden. (WHERE COUNT = zutatenanzahl)