(MySQL) Abfrage-Problem
Knud
- datenbank
0 Ilja0 Knud0 Ilja0 knud0 Ilja0 Axel Richter0 Ilja0 Axel Richter0 Ilja
0 Axel Richter0 Knud
Hallo,
ich habe die folgende Abfrage definiert:
SELECT a. * , b.vorname, b.name, b.verantwortlich, c.bezeichnung, c.farbe
FROM (
mitarbeiter AS b
LEFT JOIN urlaubdaten AS a ON a.personalnummer = b.personalnummer
)
LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE (
a.urlaubvon
LIKE '2004-%' OR a.urlaubbis
LIKE '2004-%'
) AND b.firma = 'Firma GmbH' AND b.abteilung = 'Einkauf'
ORDER BY a.personalnummer, a.urlaubvon
Diese Abfrage liefert mir leider nur diejenigen Mitarbeiter, die auch einen Eintrag in der Tabelle urlaubsdaten haben.
Wie stelle ich nun die Abfrage um, dass ich alle Mitarbeiter einer Abteilung und Firma bekomme, unabhängig davon, ob ein Eintrag existiert?
Leider funktioniert das (+) nur bei Oracle. Und ich habs leider nicht hinbekommen, die Abfrage so umzustellen, dass ein
where a.personalnummer is NULL
miteingebaut werden kann.
Wäre dankbar für nen Tipp,
Gruß,
Knud
yo,
Leider funktioniert das (+) nur bei Oracle.
das (+) ist nichts anderes als ein outer join, nur halt eine andere syntax.
lass doch mal die klammern um den ersten join weg.
Ilja
yo,
Leider funktioniert das (+) nur bei Oracle.
das (+) ist nichts anderes als ein outer join, nur halt eine andere syntax.
lass doch mal die klammern um den ersten join weg.
Ilja
Hmm, verstehe ich nicht ganz.
Was meinst Du mit outer join?
Wenn ich die Join Syntax weglasse und den select etwa so ausbaue:
select a.*,b.*,c* from telefon b,urlaubdaten a,urlaubarten,c where...
...kommt dasselbe raus. Nur die Sätze, die auch in a _und_ b sind.
Gruß,
Knud
yo,
nicht die gesamte join syntax weglassen, sondern nur die klammern darum.
Ilja
yo,
nicht die gesamte join syntax weglassen, sondern nur die klammern darum.
Ilja
Auch wenn ich _nur_ die Klammern weglasse, erhalte ich dasselbe Ergebnis:
Nur der eine Satz der auch in urlaubdaten existiert, wird angezeigt.
Gruß,
Knud
yo,
ich kann den fehler im moment auch nicht erkennen, LEFT JOIN sollte ja eigentliche alle mitarbeiter auflisten. es gibt aber einenw eg, um sich den problem anzunähern. anstelle gleiche alle beiden JOINS auszuführen. versuch doch erst mal nur den ersten, um zu sehen, ob da noch alle mitarbeiter mit an board sind.
Ilja
Hallo,
ich kann den fehler im moment auch nicht erkennen, LEFT JOIN sollte ja eigentliche alle mitarbeiter auflisten.
Tut es auch. Nur dann sagt er doch in der WHERE-Klausel, dass er nur die Datensätze will, bei denen die Daten in Feldern der Tabelle urlaubdaten bestimmte Anforderungen erfüllen. Damit schließt er alle Datensätze aus, bei denen die Felder der Tabelle urlaubdaten NULL enthalten. Das sind aber genau die Datensätze, die durch das LEFT JOIN zusätzlich, im Gegensatz zum INNER JOIN, hinzugekommen sind.
viele Grüße
Axel
yo,
das sehe ich anders, leztlich werden in der where klausel nur datensätze der einzelnen tabellen gefiltert, bevor der left join ausgeführt wird. die rechte tabelle des left joins könnte praktisch leer sein und er sollte immer noch alle datensätze der linken tabllen anzeigen.
Ilja
Hallo,
das sehe ich anders, leztlich werden in der where klausel nur datensätze der einzelnen tabellen gefiltert, bevor der left join ausgeführt wird. die rechte tabelle des left joins könnte praktisch leer sein und er sollte immer noch alle datensätze der linken tabllen anzeigen.
Nein. Die allgemeine Syntax ist:
SELECT Feldliste FROM Tabellenausdruck WHERE Kriterien
wobei:
Tabellenausdruck:= Ein Ausdruck, der eine oder mehrere Tabellen kennzeichnet, aus denen Daten abgerufen werden. Der Ausdruck kann ein einzelner Tabellenname sein, ein Name einer gespeicherten Abfrage oder ein zusammengesetzter Name, der sich aus einer Verknüpfung (INNER JOIN, LEFT JOIN oder RIGHT JOIN) ergibt.
Kriterien:= Ein Ausdruck mit Kriterien, die Datensätze erfüllen müssen, damit sie in das Abfrageergebnis aufgenommen werden.
Mit "Datensätze" sind dabei die Datensätze gemeint, welche aus dem Tabellenausdruck hervorgehen. Im Tabellenausdruck kann es eine WHERE-Klausel nur dann geben, wenn es sich dort um Unterabfragen handelt.
So könnte, meiner Meinung nach, die Lösung des Problems aussehen:
SELECT a.*, b.vorname, b.name, b.verantwortlich, c.bezeichnung, c.farbe
FROM
(mitarbeiter AS b LEFT JOIN urlaubdaten AS a ON a.personalnummer = b.personalnummer) LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE (a.urlaubvon LIKE '2004-%' OR a.urlaubbis LIKE '2004-%' OR (a.urlaubvon IS NULL AND a.urlaubbis IS NULL))
AND b.firma = 'Firma GmbH' AND b.abteilung = 'Einkauf'
ORDER BY a.personalnummer, a.urlaubvon
viele Grüße
Axel
yo,
bei mir werden erst alle where kritereien ausgeführt und dann der/die join/s gebildet. und wnen ich deine syntax richtig interpretiere, dann sagt sie genau das auch aus. was natürlich sien kann ist, dass alle mitarbeiter dieser firma und abteilung schon zufälling einen urlaubsplan haben. aber davon gehe ich mal nicht aus.
wie gesagt, mein tip wäre immer noch, mal erst einmal einen join durchzuführen und auch die where kriterien nacheinander reinzunehmen, um zu sehen, zu wlechen ergebnissen das führt. das bringt einem machmal auf die richtige spur.
Ilja
Hallo,
ich habe die folgende Abfrage definiert:
SELECT a. * , b.vorname, b.name, b.verantwortlich, c.bezeichnung, c.farbe
^Diese Lücke ist hier falsch.
FROM (
mitarbeiter AS b
LEFT JOIN urlaubdaten AS a ON a.personalnummer = b.personalnummer
)
LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE (
a.urlaubvon
LIKE '2004-%' OR a.urlaubbis
LIKE '2004-%'
) AND b.firma = 'Firma GmbH' AND b.abteilung = 'Einkauf'
ORDER BY a.personalnummer, a.urlaubvonDiese Abfrage liefert mir leider nur diejenigen Mitarbeiter, die auch einen Eintrag in der Tabelle urlaubsdaten haben.
Das ist logisch. Bei Dir hat die Tabelle "urlaubdaten" den Alias a und Du willst doch ausdrücklich _nur_ Datensätze, bei denen gilt:
a.urlaubvon LIKE '2004-%' OR a.urlaubbis LIKE '2004-%'
Bei Datensätzen, die Werte in mitarbeiter, aber _keine_ Werte in urlaubdaten haban, haben diese Felder _beide_ den Wert NULL.
viele Grüße
Axel
Hallo,
Diese Abfrage liefert mir leider nur diejenigen Mitarbeiter, die auch einen Eintrag in der Tabelle urlaubsdaten haben.
Das ist logisch. Bei Dir hat die Tabelle "urlaubdaten" den Alias a und Du willst doch ausdrücklich _nur_ Datensätze, bei denen gilt:a.urlaubvon LIKE '2004-%' OR a.urlaubbis LIKE '2004-%'
Bei Datensätzen, die Werte in mitarbeiter, aber _keine_ Werte in urlaubdaten haban, haben diese Felder _beide_ den Wert NULL.
viele Grüße
Axel
Aber auch wenn ich die Abfrage dann so formuliere...
SELECT a. * , b.vorname, b.name, b.verantwortlich, c.bezeichnung, c.farbe
FROM (
urlaubdaten AS a
LEFT JOIN telefon AS b ON a.personalnummer = b.personalnummer
)
LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE (
a.personalnummer IS NULL OR (
a.urlaubvon
LIKE '2004-%' OR a.urlaubbis
LIKE '2004-%'
)
) AND b.firma = 'Firma GmbH' AND b.abteilung = 'Einkauf'
ORDER BY a.personalnummer, a.urlaubvon
... erscheint bei mir nur der einer Satz, der in Urlaubdaten vorhanden ist.
Gruß,
Knud
Hallo,
Aber auch wenn ich die Abfrage dann so formuliere...
SELECT a. * , b.vorname, b.name, b.verantwortlich, c.bezeichnung, c.farbe
^Diese Lücke ist immer noch falsch.
FROM (
urlaubdaten AS a
^Aus dieser Tabelle werden alle Datensätze genommen.
LEFT JOIN telefon AS b ON a.personalnummer = b.personalnummer
^Was ist plötzlich telefon? Wo sind die Mitarbeiter geblieben?
)
LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE (
a.personalnummer IS NULL OR (
^Das wird wahrscheinlich nie zutreffen, weil aus a ohnehin alle Datensätze genommen werden.
a.urlaubvon
LIKE '2004-%' OR a.urlaubbis
LIKE '2004-%'
)
) AND b.firma = 'Firma GmbH' AND b.abteilung = 'Einkauf'
ORDER BY a.personalnummer, a.urlaubvon... erscheint bei mir nur der einer Satz, der in Urlaubdaten vorhanden ist.
Das ist wieder logisch, weil die Tabelle urlaubarten im LEFT JOIN ganz links steht.
Vergleichst Du mal bitte diese Abfrage mit der von Dir im Ausgangsposting vorgestellten:
SELECT a. * , b.vorname, b.name, b.verantwortlich, c.bezeichnung, c.farbe
FROM (
mitarbeiter AS b
LEFT JOIN urlaubdaten AS a ON a.personalnummer = b.personalnummer
)
LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE (
a.urlaubvon
LIKE '2004-%' OR a.urlaubbis
LIKE '2004-%'
) AND b.firma = 'Firma GmbH' AND b.abteilung = 'Einkauf'
ORDER BY a.personalnummer, a.urlaubvon
und sagst mir dann, ob Du mich veralbern willst?
viele Grüße
Axel