Einfache Verknüpfungen

Neben den bisher gezeigten Funktionalitäten von SQL sind auch Joins von großer Bedeutung. Mit Hilfe von Joins wird es möglich, Daten aus verschiedenen Tabellen zusammenzusuchen und in ein Ergebnis zu integrieren.

Legen wir erst eine Tabelle an, die Informationen über Kinder speichert und auf die Sozialversicherung der Eltern verweist:

test=# CREATE TABLE t_kind (eltern_svnr varchar(12), vorname text);
CREATE TABLE

Fügen wir nun einige Datensätze ein, um in weiterer Folge ein wenig damit experimentieren zu können:

test=# INSERT INTO t_kind VALUES ('123456', 'Karin');
INSERT 4900010 1
test=# INSERT INTO t_kind VALUES ('123456', 'Claudia');
INSERT 4900011 1
test=# INSERT INTO t_kind VALUES ('2345', 'Bernd');
INSERT 4900012 1
test=# INSERT INTO t_kind VALUES ('9876', 'Leni');
INSERT 4900013 1
test=# INSERT INTO t_kind VALUES ('9876', 'Leopold');
INSERT 4900014 1
test=# INSERT INTO t_kind VALUES ('0000', 'Edgar');
INSERT 4900015 1
test=# SELECT * FROM t_kind;
 eltern_svnr | vorname
-------------+---------
 123456      | Karin
 123456      | Claudia
 2345        | Bernd
 9876        | Leni
 9876        | Leopold
 0000        | Edgar
(6 rows)

Sehen wir uns jetzt einen einfachen Join an. Die Idee hinter der Abfrage ist, alle Kinder zu finden, die Eltern haben:

test=# SELECT t_person.*, t_kind.vorname 
	FROM t_person, t_kind 
	WHERE t_person.svnr = t_kind.eltern_svnr;
  svnr  |     name      | vorname
--------+---------------+---------
 123456 | Markus Eisner | Claudia
 123456 | Markus Eisner | Karin
 2345   | Gaika Huber   | Bernd
 9876   | Gaika Huber   | Leopold
 9876   | Gaika Huber   | Leni
(5 rows)

In der FROM-Clause listen wir beide Tabellen, die wir zuvor definiert haben. In der WHERE-Clause setzen wir schließlich je eine Spalte der beiden Tabellen miteinander gleich. So stellen wir sicher, dass die Eltern den richtigen Kindern zugeordnet werden. Würde wir das nicht tun, hätte PostgreSQL eine böse Überraschung für uns bereit:

test=# SELECT count(*) FROM t_person, t_kind;
 count
-------
    42
(1 row)

Joinen wir zwei Tabellen miteinander OHNE eine entsprechende WHERE Clause anzugeben, liefert eine relationale Datenbank das sogenannte karthesische Produkt der beiden Tabellen. Da die Ergebnismenge doch etwas größer ist, haben wir einfach nur die Anzahl der Datensätze gezählt - es ist offensichtlich, dass wir nicht 42 Kinder respektive Eltern in der Datenbank haben. Wie Sie sehen ist ein Kriterium, das die Tabellen miteinander verbindet von essentieller Bedeutung.

Im nächsten Beispiel wollen wir unser SQL-Statement ein wenig verfeinern und versuchen die Eltern von 'Claudia' zu finden:

test=# SELECT t_person.*, t_kind.vorname 
	FROM t_person, t_kind 
	WHERE t_person.svnr = t_kind.eltern_svnr 
		AND t_kind.vorname = 'Claudia';
  svnr  |     name      | vorname
--------+---------------+---------
 123456 | Markus Eisner | Claudia
(1 row)

Wir benötigen in diesem Fall eine zusätzliche WHERE-Clause, die den Datenbestand auf die entsprechenden Eltern einschränkt.

Klarerweise ist es auch möglich, Joins mit Aggregierungsfunktionen zu kombinieren. Die Vorgehensweise unterscheidet sich dabei nicht von der, die wir bereits gesehen haben:

test=# SELECT svnr, name, COUNT(*) 
	FROM t_person, t_kind 
	WHERE t_person.svnr = t_kind.eltern_svnr 
	GROUP BY svnr, name;
  svnr  |     name      | count
--------+---------------+-------
 9876   | Gaika Huber   |     2
 2345   | Gaika Huber   |     1
 123456 | Markus Eisner |     2
(3 rows)

Wieder benötigen wir eine GROUP BY Clause, um sicherzustellen, dass die Aggregierung korrekt formuliert ist. Auch HAVING-Clauses können bequem in Kombination mit Aggregierungen verwendet werden:

test=# SELECT svnr, name, COUNT(*) 
	FROM t_person, t_kind 
	WHERE t_person.svnr = t_kind.eltern_svnr 
	GROUP BY svnr, name 
	HAVING COUNT(*) > 1 
	ORDER BY svnr;
  svnr  |     name      | count
--------+---------------+-------
 123456 | Markus Eisner |     2
 9876   | Gaika Huber   |     2
(2 rows)

Das Beispiel zeigt, wie wir nur die Eltern finden können, die zwei oder mehr Kinder haben.

Joins können nicht nur für zwei Tabellen durchgeführt werden. Im Prinzip ist die Anzahl der Tabellen, die für einen Join herangezogen werden können, nicht limitiert. Zu beachten ist nur, dass Sie in der WHERE-Clause für jede zusätzliche Tabelle in der FROM-Clause eine weitere Restriktion benötigen, die zwei Tabellen miteinander verbindet, da Sie sonst wieder ein karthesisches Produkt erhalten.

Bisher haben wir die Tabellen, die an einem Join beteiligt sind, einfach in der FROM-Clause gelistet. Diese Syntax ist weit verbreitet und scheint auch sehr beliebt zu sein. Neben dieser 'impliziten' Schreibweise gibt es jedoch noch eine weitere Möglichkeit, einen Join zu formulieren:

test=# SELECT svnr, name 
	FROM t_person JOIN t_kind 
		ON (t_person.svnr = t_kind.eltern_svnr) 
	LIMIT 3;
  svnr  |     name
--------+---------------
 123456 | Markus Eisner
 123456 | Markus Eisner
 2345   | Gaika Huber
(3 rows)

In diesem Fall haben wir einen sogenannten expliziten Join verwendet. Das gezeigte Statement ist equivalent zum folgendem Code:

test=# SELECT svnr, name  
	FROM t_person, t_kind 
	WHERE t_person.svnr = t_kind.eltern_svnr 
	LIMIT 3;
  svnr  |     name
--------+---------------
 123456 | Markus Eisner
 123456 | Markus Eisner
 2345   | Gaika Huber
(3 rows)

Früher hat man explizite Joins teilweise verwendet, um die Joinreihenfolge von Tabellen positiv zu beinflussen. Das ist jedoch heutzutage nur mehr in den seltensten Fällen von Nutzen. Die explizite Syntax zum Joinen von Tabellen wird bei einfachen Joins nur mehr eher selten eingesetzt.

Es gibt auch noch eine weitere Syntax, die man verwenden kann:

test=# SELECT svnr, name 
	FROM t_person INNER JOIN t_kind 
		ON (t_person.svnr = t_kind.eltern_svnr) LIMIT 3;
  svnr  |     name
--------+---------------
 123456 | Markus Eisner
 123456 | Markus Eisner
 2345   | Gaika Huber
(3 rows)

Alle bisher gezeigten Joins gehören zur Gruppe der sogenannten Inner Joins, daher kann auch das Schlüsselwort INNER in den Join eingebaut werden.


Cybertec Schönig & Schönig GmbH
PostgreSQL support, training, consulting
www.postgresql-support.de