SQL: Feststellung, ob zwei Tabellen die gleichen Daten haben

Aus DBWiki
Wechseln zu: Navigation, Suche

Zurück zur Übersicht



Mit SQL-Dialekten, die EXCEPT bzw. MINUS unterstützen, lässt sich das Problem mit relativ geringem Aufwand lösen. In Access ist der Aufwand relativ groß, weil jeweils zwei Teilabfragen mit Unterabfragen benötigt werden, die zu vereinigen sind.

Als Ausgangsbasis verwenden wir wieder eine Abfrage namens v, die unsere zweite Tabelle simuliert. Dabei werden die Mitarbeiter aus Abteilung 10 ausgeschlossen und für Mitarbeiter Dreher wird der Datensatz verdoppelt.

SELECT * FROM mitarbeiter
WHERE  abt_nr > 10
UNION  ALL
SELECT * FROM mitarbeiter
WHERE  ma_name = 'Dreher'

Die Daten in v stellen sich dann so dar:

ma_nr ma_name job mgr eingestellt gehalt provision abt_nr
7369 Schmidt Sachbearbeiter 7902 17.02.1981 800 (Null) 20
7499 Allard Handelsvertreter 7698 20.02.1981 1.600 300 30
7521 Wecker Handelsvertreter 7698 22.02.1981 1.250 500 30
7566 Johann Abteilungsleiter 7839 12.04.1981 2.975 (Null) 20
7654 Mertens Handelsvertreter 7698 28.09.1981 1.250 1.400 30
7698 Blank Abteilungsleiter 7839 11.05.1981 2.850 (Null) 30
7788 Scheidt Referent 7566 13.07.1987 3.000 (Null) 20
7844 Dreher Handelsvertreter 7698 18.09.1981 1.500 0 30
7876 Adam Sachbearbeiter 7788 13.07.1987 1.100 (Null) 20
7900 Jakobs Sachbearbeiter 7698 03.12.1981 950 (Null) 30
7902 Fuhrmann Referent 7566 03.12.1981 3.000 (Null) 20
7844 Dreher Handelsvertreter 7698 18.09.1981 1.500 0 30

Lösung mittels EXCEPT-Klausel

SELECT * FROM ( SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, COUNT(*) AS cnt
                FROM   v
                GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr
                EXCEPT
                SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, COUNT(*) AS cnt
                FROM   mitarbeiter
                GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr )
UNION ALL
SELECT * FROM ( SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, COUNT(*) AS cnt
                FROM   mitarbeiter
                GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr
                EXCEPT
                SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, COUNT(*) AS cnt
                FROM   v
                GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr )

Dieser DBFiddle zeigt zeigt das Ergebnis.

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.

SELECT *
FROM   ( SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, Count(*) AS cnt
         FROM   v
         GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr ) AS v0
WHERE  NOT EXISTS ( SELECT NULL
                    FROM   ( SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, Count(*) AS cnt
                             FROM   mitarbeiter
                             GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr ) AS m0
                    WHERE  v0.ma_nr            = m0.ma_nr              AND
                           v0.ma_name          = m0.ma_name            AND
                           v0.job              = m0.job                AND
                           v0.mgr              = m0.mgr                AND
                           v0.eingestellt      = m0.eingestellt        AND
                           v0.gehalt           = m0.gehalt             AND
                           Nz(v0.provision, 0) = Nz(m0.provision, 0)   AND
                           v0.abt_nr           = m0.abt_nr             AND
                           v0.cnt              = m0.cnt )
UNION ALL
SELECT *
FROM   ( SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, Count(*) AS cnt
         FROM   mitarbeiter
         GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr ) AS m1
WHERE  NOT EXISTS ( SELECT NULL
                    FROM   ( SELECT ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr, Count(*) AS cnt
                             FROM   v
                             GROUP  BY ma_nr, ma_name, job, mgr, eingestellt, gehalt, provision, abt_nr ) AS v1
                    WHERE  m1.ma_nr            = v1.ma_nr              AND
                           m1.ma_name          = v1.ma_name            AND
                           m1.job              = v1.job                AND
                           m1.mgr              = v1.mgr                AND
                           m1.eingestellt      = v1.eingestellt        AND
                           m1.gehalt           = v1.gehalt             AND
                           Nz(m1.provision, 0) = Nz(v1.provision, 0)   AND
                           m1.abt_nr           = v1.abt_nr             AND
                           m1.cnt              = v1.cnt )

Ergebnis der Access-Lösung:

ma_nr ma_name job mgr eingestellt gehalt provision abt_nr cnt
7844 Dreher Handelsvertreter 7698 18.09.1981 1500 0 30 2
7782 Kühne Abteilungsleiter 7839 19.06.1981 2450 (Null) 10 1
7839 König Hauptgeschäftsführer (Null) 17.11.1981 5000 (Null) 10 1
7844 Dreher Handelsvertreter 7698 18.09.1981 1500 0 30 1
7934 Müller Sachbearbeiter 7782 23.01.1982 1300 (Null) 10 1



Zurück zur Übersicht