Geschrieben von

SQL: Daten verbinden

Data Analytics

Um Daten in SQL miteinander zu verbinden gibt es verschiedene Möglichkeiten:

In diesem Artikel gebe ich eine grobe Einführung und Übersicht.

JOIN

Ein JOIN kombiniert Spalten aus einer oder mehreren Tabellen auf Basis einer Kondition. Dabei gibt es 4 verschiedene JOIN-Typen (hier auch inkl. deren Untertypen):

Wörter in Großbuchstaben haben eine SQL-Syntax, während Self-Join, Semi-Join und Anti-Join über keine entsprechende SQL-Syntax verfügen.

INNER JOIN

Ein INNER JOIN speichert nur Datensätze, in denen die Schlüsselfelder in beiden abgefragten Tabellen existieren:

Die Syntax ist wie folgt:

SELECT t1.id, t1.wert, t2.wert
FROM linkeTabelle AS t1
INNER JOIN rechteTabelle AS t2
ON t1.id = t2.id;

Self-Join
Bei einem Self-Join handelt es sich um eine innere Verknüpfung, mit der eine Tabelle mit sich selbst verbunden werden kann. Self-Join ist eine Unterart von INNER JOIN. Die Abfrage von Self-Joins kommt zum Einsatz, wenn man Werte in einem Feld mit anderen Werten desselben Felds aus der gleichen Tabelle vergleiche möchte.

Ein Beispiel wäre eine Tabelle mit Arbeitskollegen, die eine Freundschaft mit Arbeitskollegen aus der selben Tabelle pflegen. Das wäre die Tabelle dafür:

IdMitarbeiterFreund_Id
1Max3
2Maria1
3Stefan2

Um nun den Namen des Mitarbeiters zusammen mit dem Freund zu erhalten, können wir ein Self-Join anwenden. Voraussetzung ist, dass die Freund_Id der Spalte “Id” entspricht. Denn nur so lässt sich die Tabelle mit sich selbst verknüpfen. Die Syntax dafür wäre:

SELECT t1.Id, t1.Mitarbeiter, t2.Mitarbeiter
FROM mitarbeiterTabelle AS t1
INNER JOIN mitarbeiterTabelle AS t2
ON t1.Freund_Id = t2.Id
ORDER BY t1.Id;

Visuell würde das so aussehen:

Und hier nochmal das Ergebnis:

OUTER JOIN

Während bei einem INNER JOIN Spalten ausgeblendet werden, die nicht der Selektionsbedingung entsprechen, werden bei einem OUTER JOIN auch übrige Tupel aus der anderen Tabelle ausgegeben.

LEFT JOIN
Ein LEFT JOIN speichert alle Datensätze aus der linken Tabelle und fügt noch zusätzlich die Übereinstimmungen mit der rechten Tabellen hinzu:

Die Syntax für ein LEFT JOIN:

SELECT t1.id, t1.wert, t2.wert
FROM linkeTabelle AS t1
LEFT JOIN rechteTabelle AS t2
ON t1.id = t2.id;

RIGHT JOIN
Ein RIGHT JOIN speichert alle Datensätze aus der rechten Tabelle und fügt noch zusätzlich die Übereinstimmungen mit der linken Tabellen hinzu:

Dafür wäre die Syntax wie folgt:

SELECT t2.id, t1.wert, t2.wert
FROM linkeTabelle AS t1
RIGHT JOIN rechteTabelle AS t2
ON t1.id = t2.id;

FULL JOIN
Ein FULL JOIN ist eine Kombination aus LEFT JOIN und RIGHT JOIN. Hier werden die Datensätze angezeigt, die in beiden Tabellen vorkommen und welche Datensätze nur in einzelnen Tabellen vorkommen:

Die Syntax dafür wäre:

SELECT t1.id, t2.id, t1.wert, t2.wert
FROM linkeTabelle AS t1
FULL JOIN rechteTabelle AS t2
USING (id);

CROSS JOIN

Ein CROSS JOIN verbindet jede Zeile der ersten Tabelle mit jeder Zeile der zweiten Tabelle:

Die Syntax sieht wie folgt aus:

SELECT table1.id AS id1, table2.id AS id2
FROM table1
CROSS JOIN table2;

Semi-Join und Anti-Join

Mit den bisherigen JOINs konnte man zur linken (Original-)Tabelle Spalten hinzufügen. Die 2 nachfolgenden JOINs benutzen die rechte Tabelle, um zu bestimmen, welche Spalten in der linken (Original-)Tabelle bestehen bleiben sollen. Ein Semi-Join und Anti-Join wird dabei ähnlich wie eine WHERE-Klausel verwendet, basierend auf den Werten der zweiten Tabelle. Daher sind Semi-Join und Anti-Join auch eine Art Unterabfragen.

Um das Konzept eines Semi-Joins zu erklären, muss man etwas ausholen. Grundsätzlich kann man sagen: Mit einem Semi-Join kann man eine Tabelle basierend auf Konditionen, die man auf einer anderen Tabelle anwendet, filtern. Gehen wir davon aus, dass wir die Gründer von Automarken wissen möchten, die vor 1980 gegründet haben. Wir haben 2 Tabellen. Die erste ist die Automarken-Tabelle. Fragen wir also alle Automarken ab, die vor 1980 gegründet wurden:

SELECT name
FROM automarken
WHERE jahr < 1980;

Die Tabelle:

name
ABC
Super Auto

Dann haben wir eine zweite Tabelle mit den Namen der Gründer inkl. ein paar weiterer Informationen. Diese Fragen wir nun ebenfalls ab:

SELECT gruender, name, position
FROM gruendung;

Die Tabelle:

gruendernameposition
MaxMega AutoManager
StefanABCCEO
MariaTop AutoManager
StefanieERTCEO

Um nun auf unser Ergebnis zu kommen, müssen wir diese Ausgabe mit der vorherigen Ausgabe filtern. Hier kommt nun eine Unterabfrage (eine Abfrage in einer Abfrage) zum Einsatz:

SELECT gruender, name, position
FROM gruendung
WHERE name IN
  (SELECT name
  FROM automarken
  WHERE jahr < 1980);

Man nutzt also ein WHERE-Klausel, um die beiden Tabellen miteinander zu kombinieren. Die erste Abfrage wird jedoch als Kondition in der WHERE-Klausel benutzt. Hier nun unser Ergebnis:

gruendernameposition
StefanABCCEO

Da "Super Auto" keinen Gründer hat, wird es hier auch nicht ausgegeben. Ein Semi-Join wählt also alle Einträge in der ersten Tabelle, deren Bedingung auf die zweite Tabelle zutreffen:

Möchte man jedoch seine erste Tabelle basierend auf Konditionen filtern, die nicht in der zweiten Tabelle vorkommen, dann bietet sich ein Anti-Join an:

Syntax wäre beispielhaft:

SELECT gruender, name, position
FROM gruendung
WHERE name NOT IN
  (SELECT name
  FROM automarken
  WHERE jahr < 1980);

UNION

Ein UNION kombiniert Zeilen aus einer oder mehreren Tabellen auf Basis einer Kondition. Auch hier gibt es verschiedene UNION-Typen:

  • UNION
  • UNION ALL
  • INTERSECT
  • EXCEPT

Die Unterschiede der UNION-Typen kann man wie folgt visualisieren:

Um UNION benutzen zu können, müssen bestimmte Anforderungen gegeben sein:

  • Jede der SELECT-Anweisungen muss dieselbe Anzahl von Bedingungen haben
  • Die ausgewählten Spalten müssen in der gleichen Reihenfolge sein
  • Die ausgewählten Spalten müssen gleiche Datentypen aufweisen

UNION

UNION enthält jeden Datensatz aus beiden Tabellen, es wird aber nicht doppelt gezählt (falls es Doppelungen gibt).

Die Syntax sieht wie folgt aus:

SELECT spalte1, spalte2
FROM tabelle1
UNION
SELECT spalte1_1, spalte2_2
FROM tabelle2
ORDER BY spalte1;

UNION ALL

UNION ALL enthält auch jeden Datensatz aus beiden Tabellen (so wie UNION), aber enthält auch doppelte Werte aus beiden Tabellen.

Die Syntax sieht wie folgt aus:

SELECT spalte1, spalte2
FROM tabelle1
UNION ALL
SELECT spalte1, spalte2
FROM tabelle2
ORDER BY spalte1;

INTERSECT

INTERSECT zeigt nur Datensätze, die in beiden Tabellen vorkommen.

Syntax:

SELECT spalte1
FROM tabelle1
INTERSECT
SELECT spalte1
FROM tabelle2;

EXCEPT

EXCEPT zeigt nur Datensätze, die einzigartig in einer Tabelle vorkommen.

Die Syntax:

SELECT spalte1, spalte2
FROM tabelle1
EXCEPT
SELECT spalte1, spalte2
FROM tabelle2;

Unterabfragen

Unterabfragen werden auch als Sub-Selects oder Sub-Querys genannt. Dabei wird in einer SQL-Abfrage eine weitere Abfrage integriert. Eine Abfrage in einer Abfrage also. Dadurch können die Ergebnisse einer Unterabfrage sofort in der neuen Abfrage verwendet werden. Meistens werden Unterabfragen in einer WHERE-Klausel verwendet (siehe Semi- und Anti-Join). Unterabfragen können aber auch in der SELECT- und FROM-Klausel benutzt werden.