SQL: Fehlende Daten aus mehreren Tabellen zurückgeben

Aus DBWiki
Wechseln zu: Navigation, Suche

Zurück zur Übersicht



Access unterstützt Outer Joins in Form eines LEFT JOIN oder eines RIGHT JOIN, ohne das Schlüsselwort OUTER anzugeben, was in anderen SQL-Dialekten optional angegeben werden darf.

Lösung für Jet-SQL

Hinweis für Access-Anwender
Um die folgenden Abfragen selbst testen zu können, müssen die Tabellen der Übungsdatenbank vorhanden sein.


Um z. B. alle Abteilungen anzuzeigen (auch jene, für die keine Mitarbeiterdaten vorhanden sind), kann man diese Abfrage verwenden:

SELECT a.abt_nr, abt_name, ma_name
FROM   mitarbeiter AS m
       RIGHT JOIN abteilung AS a
               ON m.abt_nr = a.abt_nr

oder diese Abfrage mit demselben Resultat:

SELECT a.abt_nr, abt_name, ma_name
FROM   abteilung AS a
       LEFT JOIN mitarbeiter AS m
              ON a.abt_nr = m.abt_nr
abt_nr abt_name ma_name
10 Buchhaltung Kühne
10 Buchhaltung König
10 Buchhaltung Müller
20 Forschung Schmidt
20 Forschung Johann
20 Forschung Scheidt
20 Forschung Adam
20 Forschung Fuhrmann
30 Verkauf Allard
30 Verkauf Wecker
30 Verkauf Mertens
30 Verkauf Blank
30 Verkauf Dreher
30 Verkauf Jakobs
40 Fertigung (Null)

Wäre auch ein Mitarbeiter ohne abt_nr vorhanden, wäre ein FULL OUTER JOIN notwendig, um Daten aus beiden fehlenden Tabellen darzustellen. Zu diesem Zweck simulieren wir mithilfe der Tabelle dual durch folgende Abfrage eine auf zwei Felder reduzierte Tabelle vw_mitarbeiter_neu.

SELECT ma_name, abt_nr FROM mitarbeiter
union  ALL
SELECT 'Kermit', NULL FROM dual


Weil Access keinen FULL OUTER JOIN unterstützt, kann man diesen durch eine Vereinigungsabfrage nachstellen:

SELECT a.abt_nr,
       abt_name,
       ma_name
FROM   vw_mitarbeiter_neu AS m
       INNER JOIN abteilung AS a
               ON m.abt_nr = a.abt_nr
UNION ALL
SELECT NULL,
       NULL,
       ma_name
FROM   vw_mitarbeiter_neu AS m
WHERE  NOT EXISTS( SELECT *
                   FROM   abteilung
                   WHERE  m.abt_nr = abt_nr )
UNION ALL
SELECT abt_nr,
       abt_name,
       NULL
FROM   abteilung AS a
WHERE  NOT EXISTS( SELECT *
                   FROM   vw_mitarbeiter_neu
                   WHERE  a.abt_nr = abt_nr )
abt_nr abt_name ma_name
20 Forschung Schmidt
30 Verkauf Allard
30 Verkauf Wecker
20 Forschung Johann
30 Verkauf Mertens
30 Verkauf Blank
10 Buchhaltung Kühne
20 Forschung Scheidt
10 Buchhaltung König
30 Verkauf Dreher
20 Forschung Adam
30 Verkauf Jakobs
20 Forschung Fuhrmann
10 Buchhaltung Müller
(Null) (Null) Kermit
40 Fertigung (Null)

Oder auch mit demselben Ergebnis (nur mit anderer Sortierung, und vermutlich etwas langsamer in der Ausführung):

SELECT a.abt_nr,
       abt_name,
       ma_name
FROM   vw_mitarbeiter_neu AS m
       LEFT JOIN abteilung AS a
              ON m.abt_nr = a.abt_nr
UNION
SELECT a.abt_nr,
       abt_name,
       ma_name
FROM   abteilung AS a
       LEFT JOIN vw_mitarbeiter_neu AS m
              ON a.abt_nr = m.abt_nr
abt_nr abt_name ma_name
(Null) (Null) Kermit
10 Buchhaltung König
10 Buchhaltung Kühne
10 Buchhaltung Müller
20 Forschung Adam
20 Forschung Fuhrmann
20 Forschung Johann
20 Forschung Scheidt
20 Forschung Schmidt
30 Verkauf Allard
30 Verkauf Blank
30 Verkauf Dreher
30 Verkauf Jakobs
30 Verkauf Mertens
30 Verkauf Wecker
40 Fertigung (Null)



Zurück zur Übersicht