Equijoins in SQL (Equijoins in SQL), Lektion, Seite 722963
https://www.purl.org/stefan_ram/pub/equijoins_sql (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
SQL-Kurs

Äquijoins in SQL  (MySQL )

Ermittelung einer Schnittmenge

Vorbereitung

Skript (MySQL )

DROP SCHEMA S; CREATE SCHEMA S; USE S;

CREATE TABLE L ( WERT VARCHAR ( 255 ));

INSERT INTO L ( WERT ) VALUES ( '1' );
INSERT INTO L ( WERT ) VALUES ( '2' );

CREATE TABLE R ( WERT VARCHAR ( 255 ));

INSERT INTO R ( WERT ) VALUES ( '1' );
INSERT INTO R ( WERT ) VALUES ( '3' );

Ermittelung einer Schnittmenge

Das obenstehende Skript erzeugt zwei Tabellen »L« und »R«, die beide die Zahl »1« enthalten.

Konsole
SELECT * FROM L;
+------+
| WERT |
+------+
| 1 |
| 2 |
+------+
SELECT * FROM R;
+------+
| WERT |
+------+
| 1 |
| 3 |
+------+

Das kartesische Produkt jener beiden Tabellen enthält alle möglichen Paare, deren erste Komponente aus der ersten Tabelle und deren zweite Komponente aus der zweiten Tabelle stammt.

Konsole
SELECT * FROM L, R;
+------+------+
| WERT | WERT |
+------+------+
| 1 | 1 |
| 2 | 1 |
| 1 | 3 |
| 2 | 3 |
+------+------+

Wählt man aus dem kartesischen Produkt nun diejenigen Paare aus, in denen beide Komponenten einander gleich sind, so erhält man alle Werte, die in beiden Tabellen vorkommen.

Konsole
SELECT * FROM L, R WHERE L.WERT = R.WERT;
+------+------+
| WERT | WERT |
+------+------+
| 1 | 1 |
+------+------+

Durch eine Projektion kann es erreicht werden, das die Werte, die in beiden Tabellen vorkommen, nicht mehr doppelt angezeigt werden.

Konsole
SELECT L.WERT FROM L, R WHERE L.WERT = R.WERT;
+------+
| WERT |
+------+
| 1 |
+------+

Ermittelung einer Zuordnung

Vorbereitung

Skript (MySQL )

DROP SCHEMA S; CREATE SCHEMA S; USE S;

CREATE TABLE ZAHL ( ZIFFERN VARCHAR ( 255 ), BEZEICHNUNG VARCHAR ( 255 ));

INSERT INTO ZAHL ( ZIFFERN, BEZEICHNUNG ) VALUES ( '0', 'Null' );
INSERT INTO ZAHL ( ZIFFERN, BEZEICHNUNG ) VALUES ( '1', 'Eins' );

CREATE TABLE NUMBER ( DIGITS VARCHAR ( 255 ), BEZEICHNUNG VARCHAR( 255 ));

INSERT INTO NUMBER ( DIGITS, BEZEICHNUNG ) VALUES ( '0', 'zero' );
INSERT INTO NUMBER ( DIGITS, BEZEICHNUNG ) VALUES ( '1', 'one' );

Ermittelung einer Zuordnung

Die Tabellen »S.ZAHL« und »S.NUMBER« enthalten deutsche beziehungsweise englische Zahlennamen.

Konsole
SELECT * FROM ZAHL;
+---------+-------------+
| ZIFFERN | BEZEICHNUNG |
+---------+-------------+
| 0 | Null |
| 1 | Eins |
+---------+-------------+
SELECT * FROM NUMBER;
+--------+-------------+
| DIGITS | BEZEICHNUNG |
+--------+-------------+
| 0 | zero |
| 1 | one |
+--------+-------------+

Durch Bildung eines kartesischen Produktes erhält man alle möglichen Paare, deren erste Komponente aus der ersten Tabelle und deren zweite Komponente aus der zweiten Tabelle stammt.

Konsole
SELECT * FROM ZAHL, NUMBER;
+---------+-------------+--------+-------------+
| ZIFFERN | BEZEICHNUNG | DIGITS | BEZEICHNUNG |
+---------+-------------+--------+-------------+
| 0 | Null | 0 | zero |
| 1 | Eins | 0 | zero |
| 0 | Null | 1 | one |
| 1 | Eins | 1 | one |
+---------+-------------+--------+-------------+

Im kartesischen Produkt sind nun diejenigen Paarungen besonders interessant, welche sich auf dieselbe Zahl beziehen, also beide zur Zahl 0 oder beide zur Zahl 1 gehören. Wir können diese durch eine Äquirestriktion auswählen.

Konsole
SELECT * FROM ZAHL, NUMBER WHERE ZIFFERN = DIGITS;
+---------+-------------+--------+-------------+
| ZIFFERN | BEZEICHNUNG | DIGITS | BEZEICHNUNG |
+---------+-------------+--------+-------------+
| 0 | Null | 0 | zero |
| 1 | Eins | 1 | one |
+---------+-------------+--------+-------------+

Ein kartesisches Produkt von Tabellen wird im Englischen auch als Join  („Verbindung“) bezeichnet.

Wird ein Join mit einer Äquiselektion kombiniert, so spricht man auch von einem Äquijoin  oder Equi-Join  oder eine Äquiverbindung  oder Äquiverbindungsabfrage. Auf englisch spricht man von einem “equijoin ”, “equi-join ” oder “equi join ”.

Während die früher eingeführten Bezeichnung „Äquiselektion“ und „Äquirestriktion“ nicht  allgemein üblich sind, ist die Bezeichnung „Equi-Join“ allgemein üblich.

Wir sagen auch, daß die Ergebnistabelle eine Join-Abhängigkeit von den beiden Basistabellen habe, da sie aus diesen durch eine Join-Operation rekonstruiert werden kann.

Wir sagen auch, daß es zwischen den beiden Basistabellen eine 1:1-Beziehung gebe, da jeweils einer Zeile der einen Tabelle genau eine Zeile der anderen Tabelle zugeordnet wird.

Wir sehen in der obigen Tabelle nun die deutschen und englischen Bezeichnungen der Zahlen richtig einander zugeordnet. Jetzt können wir beispielsweise nur auf die Wörter projizieren, um eine kleine Übersetzungstabelle zu erhalten.

Konsole
SELECT ZAHL.BEZEICHNUNG, NUMBER.BEZEICHNUNG FROM ZAHL, NUMBER WHERE ZIFFERN = DIGITS;
+-------------+-------------+
| BEZEICHNUNG | BEZEICHNUNG |
+-------------+-------------+
| Null | zero |
| Eins | one |
+-------------+-------------+

Da die Spalten »ZIFFERN« beziehungsweise »DIGITS« für die Zuordnung  verwendet werden, nennen wir sie auch Zuordnungsspalten.

Wir können keine  Ansichten für einige der obenstehenden Abfragen definieren, weil mehrere Spalten mit gleichem Namen in einer Ansicht nicht  gestattet sind! Wir werden allerdings später lernen, wie wir den Makel der gleichnamigen Spalten beheben können.

Aussprachehinweis
duplicate (n) ˈduːplɪkət

Übungsfragen

/   Veränderung einer Abfrage

Wie muß die folgende SELECT-Abfrage verändert werden, wenn nur die beiden Spalten »VORNAME« und »NACHNAME« aus der derzeitigen Ergebnistabelle angezeigt werden sollen?

Vorbereitungsskript

DROP SCHEMA S; CREATE SCHEMA S; USE S;

CREATE TABLE VORNAME ( PERSON VARCHAR ( 255 ), VORNAME VARCHAR ( 255 ));

INSERT INTO VORNAME ( PERSON, VORNAME ) VALUES ( 1, 'Hans' );
INSERT INTO VORNAME ( PERSON, VORNAME ) VALUES ( 2, 'Lotte' );

CREATE TABLE NACHNAME ( PERSON1 VARCHAR ( 255 ), NACHNAME VARCHAR ( 255 ));

INSERT INTO NACHNAME ( PERSON1, NACHNAME ) VALUES ( 1, 'Fischer' );
INSERT INTO NACHNAME ( PERSON1, NACHNAME ) VALUES ( 2, 'Mayer' );

Konsole
SELECT * FROM VORNAME, NACHNAME WHERE PERSON = PERSON1;
+--------+---------+---------+----------+
| PERSON | VORNAME | PERSON1 | NACHNAME |
+--------+---------+---------+----------+
| 1 | Hans | 1 | Fischer |
| 2 | Lotte | 2 | Mayer |
+--------+---------+---------+----------+

Übungsaufgaben

/   Namen zuordnen

Skript (MySQL )

DROP SCHEMA S; CREATE SCHEMA S; USE S;

CREATE TABLE VORNAME ( PERSON VARCHAR ( 255 ), VORNAME VARCHAR ( 255 ));
INSERT INTO VORNAME ( PERSON, VORNAME ) VALUES ( 0, 'Eberhard' );
INSERT INTO VORNAME ( PERSON, VORNAME ) VALUES ( 1, 'Ingeborg' );
INSERT INTO VORNAME ( PERSON, VORNAME ) VALUES ( 2, 'Helmut' );

CREATE TABLE NACHNAME ( PERSON VARCHAR ( 255 ), NACHNAME VARCHAR ( 255 ));
INSERT INTO NACHNAME ( PERSON, NACHNAME ) VALUES ( 2, 'Eberhard' );
INSERT INTO NACHNAME ( PERSON, NACHNAME ) VALUES ( 0, 'Hochmann' );
INSERT INTO NACHNAME ( PERSON, NACHNAME ) VALUES ( 1, 'Quednau' );

Kurzdoku
Tabelle »VORNAME«: Die Person mit der Kennzahl »PERSON« hat den Vornamen »VORNAME«.
Tabelle »NACHNAME«: Die Person mit der Kennzahl »PERSON« hat den Nachnamen »NACHNAME«.

Die beiden obenstehenden Tabellen enthalten Vor- und Nachnamen von Personen, wobei gleiche Kennzahlen in der Spalte »PERSON« in den beiden Tabellen jeweils für die gleiche Person stehen. Erzeugen Sie mit einer Abfrage eine abgeleitete Tabelle, die zwei Spalten mit den Vor- und Nachnamen der Personen und für jede Person genau eine Zeile mit deren Vor- und Nachnamen enthält. (Außer den genannten Spalten und Zeilen soll das Ergebnis der Abfrage keine weiteren Spalten oder Zeilen enthalten.)

Mögliches Ergebnis der zu erstellenden Abfrage
+----------+----------+
| VORNAME | NACHNAME |
+----------+----------+
| Eberhard | Hochmann |
| Ingeborg | Quednau |
| Helmut | Eberhard |
+----------+----------+

/   Schnittmenge ermitteln

Ermitteln Sie durch eine Abfrage alle Namen aus den Tabellen der vorigen Übungsaufgabe, die sowohl Vor- als auch Nachnamen sind.

Mögliches Ergebnis der zu erstellenden Abfrage
+----------+
| VORNAME |
+----------+
| Eberhard |
+----------+

Einfügen in Ansichten *

Wenn eine Ansicht als eine Verbindungsabfrage definiert wurde, so kann man in diese Ansicht im allgemeinen nicht  so Zeilen einfügen, daß diese dann auf die zugrundeliegenden Basistabellen aufgeteilt werden und bei Bedarf Zeilen in Basistabellen eingefügt werden. Hier müssen die Zeilen direkt  in die Basistabellen eingefügt werden.

Effizienz *

Man darf sich nicht vorstellen, daß das möglicherweise sehr große kartesische Produkt zunächst erst einmal als eine riesige Tabelle zwischengespeichert wird. Datenbanksystem führen solche Anfrage in der Regel recht effizient aus und verwenden Techniken, um die Wege bei der Ermittlung eines Äquijoins abzukürzen, beispielsweise indem mehrere Bearbeitungsschritte, die konzeptionell hintereinander abgearbeitet werden müssen zu einem einzigen Schritt verbunden werden. Dadurch kann es dann beispielsweise vermieden werden, daß Zeilen des kartesischen Produktes, die bei der Selektion gleich wieder entfernt werden, überhaupt erst unnötigerweise erzeugt werden.

Gleichheit ohne Beachtung von Groß- und Kleinschreibung *

Das folgende Beispiel zeigt wie zwei Tabelle mit Buchstaben so miteinander verbunden werden können, daß einem großen Buchstaben der zugehörige kleine Buchstabe zugeordnet wird.

Dies gelingt hier aber nur wegen einer eigentlich nicht ganz korrekten Eigenart der Gleichheitsprüfung von Texten in MySQL: Ein großer Buchstabe wird dem entsprechenden kleinen Buchstaben als gleich angesehen.

Skript (MySQL )

DROP SCHEMA S; CREATE SCHEMA S; USE S;

CREATE TABLE MAJUSKEL ( MAJUSKEL VARCHAR ( 255 ));

INSERT INTO MAJUSKEL ( MAJUSKEL ) VALUES ( 'A' );
INSERT INTO MAJUSKEL ( MAJUSKEL ) VALUES ( 'B' );
INSERT INTO MAJUSKEL ( MAJUSKEL ) VALUES ( 'C' );

CREATE TABLE MINUSKEL ( MINUSKEL VARCHAR ( 255 ));

INSERT INTO MINUSKEL ( MINUSKEL ) VALUES ( 'a' );
INSERT INTO MINUSKEL ( MINUSKEL ) VALUES ( 'b' );
INSERT INTO MINUSKEL ( MINUSKEL ) VALUES ( 'c' );

SELECT * FROM MAJUSKEL, MINUSKEL WHERE MAJUSKEL = MINUSKEL;

+----------+----------+
| MAJUSKEL | MINUSKEL |
+----------+----------+
| A | a |
| B | b |
| C | c |
+----------+----------+

Falls nicht gewünscht, daß Groß- und Kleinschreibung einander gleichgesetzt werden, kann »WHERE« und »BINARY« verwendet werden.

Konsole
SELECT * FROM MAJUSKEL, MINUSKEL WHERE BINARY MAJUSKEL = MINUSKEL;
Empty set

Vergleich mit der mathematischen Mengenschreibweise (Mengenbeschreibung)

In der Mathematik kennt man Mengenbeschreibungen in der Schreibweise { x  ∈ G | f(x ) = 7 }. Die als Beispiel gezeigte Mengenbeschreibung entspricht in etwa der SQL-Abfrage »SELECT * FROM G WHERE F = '7'«.

 

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram722963 stefan_ram:722963 Equijoins in SQL Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd722963, slrprddef722963, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/equijoins_sql