MYSQL Bedingungen verschachteln
be@sy
- datenbank
0 Yinan0 Markus Thomas0 Vinzenz Mai
Hallo Zusammen,
ich versuche gerade verzweifelt ein Select über 4 Tabellen zu machen.
Diese werden über ihre FKS verbunden. Die Tabellen heißen:
fahrzeug, inventar, belegung und standort.
Dabei ist Fahrzeug ein Inventar. Dieses hat wiederum eine Belegung (d.h. hier sind Start- und Enddatum der Belegung angegeben).Jedes Inventar ist einem Standort zugeordnet.
Ich möchte mir nun anzeigen lassen, welches Fahrzeug vom Datum x bis y frei ist. Wenn ich dies nur über Belegung mache, sieht die Sache so aus:
SELECT *
FROM belegung
WHERE START < '2007-01-27'
AND ende < '2007-01-27'
OR START > '2007-02-28'
AND ende > '2007-02-28'
Ich bekomme auch tatsächlich nur die Zeilen angegeben, wo Start und Ende-Zeitpunkt nicht im gesuchten Zeitraum liegen.
Versuche ich das jetzt allerdings so aufzubauen, dass ich das Fahrzeug herausbekomme, das über Inventar an Belegung hängt, bekomme ich etwas, das aussieht wie ein Kreuzprodukt über alle 4 Tabellen. Mein SQL dazu sieht so aus:
SELECT * FROM fahrzeug, inventar , belegung, standort WHERE
inventar.id=belegung.inventar_id
AND START < '2007-01-27'AND ende < '2007-01-27'
OR START > '2007-02-28' AND ende > '2007-02-28'
AND inventar.id= fahrzeug.inventar_id
AND standort.id=inventar.standort_id
Ich würde gerne wissen, wie ich es schaffe der DB klar zu machen welche Bedingungen zusammengehören und wo diese durch OR getrennt werden. Was mache ich falsch?
Vielen Dank
Be@sy
SELECT * FROM fahrzeug, inventar , belegung, standort WHERE
inventar.id=belegung.inventar_id
AND START < '2007-01-27'AND ende < '2007-01-27'
OR START > '2007-02-28' AND ende > '2007-02-28'
AND inventar.id= fahrzeug.inventar_id
AND standort.id=inventar.standort_id
Ich würde vorschlagen, klammern zu benutzen (um ehrlich zu sein hab ich jetzt nicht 100%ig verstanden, wo genau das problem liegt, die folgende Lösung ist für das, was ich so herausverstanden habe ^^):
SELECT *
FROM fahrzeug, inventar , belegung, standort
WHERE inventar.id=belegung.inventar_id
AND
(
(START < '2007-01-27'AND ende < '2007-01-27')
OR
(START > '2007-02-28' AND ende > '2007-02-28')
)
AND
inventar.id= fahrzeug.inventar_id
AND
standort.id=inventar.standort_id
Weiß jetzt nicht ob das für dein Problem relevant ist, wenn nicht tuts mir leid ^^
mfg
Yinan
Hi Yinan,
hatte vergessen zu erwähnen, dass ichs mit Klammern bereits versucht hab. Bei mir kam aber immer nur ne blöde Fehlermeldung. Bin wahrscheinlich einfach schon betriebsblind vom Davorsitzen und Grübeln.
Die von dir gesetzten Klammern funktionieren. Vielen Dank!! Konntest mir also helfen obwohl du die Frage nicht ganz verstanden hattest ;-)
MFG
Be@sy
Hi,
da das Problem ja wohl schon gelöst ist, hier nur noch ne kleine Anmerkung:
((START < '2007-01-27'AND ende < '2007-01-27')
OR (START > '2007-02-28' AND ende > '2007-02-28'))
kannst auch einfacher so schreiben:
(START < '2007-02-28' AND ende > '2007-01-27')
Grüße
Bezkeroon
Hi Yinan,
hatte vergessen zu erwähnen, dass ichs mit Klammern bereits versucht hab. Bei mir kam aber immer nur ne blöde Fehlermeldung. Bin wahrscheinlich einfach schon betriebsblind vom Davorsitzen und Grübeln.
Die von dir gesetzten Klammern funktionieren. Vielen Dank!! Konntest mir also helfen obwohl du die Frage nicht ganz verstanden hattest ;-)
MFG
Be@sy
Hallo,
Ich würde gerne wissen, wie ich es schaffe der DB klar zu machen welche Bedingungen zusammengehören und wo diese durch OR getrennt werden. Was mache ich falsch?
Du setzt keine KLammern, z.B. so:
SELECT * FROM fahrzeug, inventar , belegung, standort
WHERE inventar.id=belegung.inventar_id
AND inventar.id=fahrzeug.inventar_id
AND standort.id=inventar.standort_id
AND (START < '2007-01-27'AND ende < '2007-01-27'
OR START > '2007-02-28' AND ende > '2007-02-28')
Gruß aus Berlin,
Markus
Hallo
Versuche ich das jetzt allerdings so aufzubauen, dass ich das Fahrzeug herausbekomme, das über Inventar an Belegung hängt, bekomme ich etwas, das aussieht wie ein Kreuzprodukt über alle 4 Tabellen. Mein SQL dazu sieht so aus:
Du solltest Klammern setzen :-)
SELECT * FROM fahrzeug, inventar , belegung, standort WHERE
inventar.id=belegung.inventar_id
AND START < '2007-01-27'AND ende < '2007-01-27'
OR START > '2007-02-28' AND ende > '2007-02-28'
AND inventar.id= fahrzeug.inventar_id
AND standort.id=inventar.standort_idIch würde gerne wissen, wie ich es schaffe der DB klar zu machen welche Bedingungen zusammengehören und wo diese durch OR getrennt werden. Was mache ich falsch?
Ich persönlich bevorzuge die explizite Join-Syntax:
SELECT
<spaltenliste> -- Ich vermeide SELECT *, wo immer ich kann
-- und wähle nur die Spalten aus, die ich wirklich
-- benötige
FROM fahrzeug f -- Aliasnamen sparen Schreibarbeit ;-)
INNER JOIN inventar i -- Explizite Joinsyntax
ON f.inventar_id = i.id
INNER JOIN standort s
ON s.id = i.standort_id
INNER JOIN belegung b
ON i.id = b.inventar_id
-- Es folgen jede Menge redundanter Klammern
-- Hättest Du das äußere Klammerpaar um Deine Zeiteinschränkungen gesetzt,
-- sollte Dein Statement das gewünschte Ergebnis liefern.
WHERE ((START < '2007-01-27'AND ende < '2007-01-27')
OR (START > '2007-02-28' AND ende > '2007-02-28'))
Für mich sind SQL-Statements mit expliziter JOIN-Syntax leichter lesbar, da JOIN-Bedingungen und Einschränkung der Ergebnismenge (WHERE-Klausel) sauber getrennt sind.
Wenn Du die Ergebnismenge weiter einschränken willst, so beachte, dass dann die äußeren Klammern, die in meiner WHERE-Klausel stehen, notwendig sind. Gleiches gilt, wenn Du die implizite JOIN-Syntax weiter verwenden willst.
Freundliche Grüße
Vinzenz