Ä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'«.