Lektion 5 | Geschachtelte SELECT-Anweisungen

Einführung

Immer wieder werden in MySQL zur Durchführung einer Abfrage Informationen benötigt, die zuerst durch eine eigene Abfrage bestimmt werden müssen.

Durch eine weitere SELECT-Anweisung als Unterabfrage in der WHERE-Klausel erhältst Du mit nur einer einzigen geschachtelten SELECT-Anweisung die gewünschten Informationen.

Beispiel:

Wir wollen wissen, wo Mike wohnt.

Gingest Du wie bisher vor, bestimmtest Du zuerst die AdressID von Mike, um dann in der nächsten Abfrage, mithilfe der ID, die Adresse zu bestimmen.

SELECT address_id
	FROM staff
	WHERE first_name = "Mike";

Ergebnis: 3

SELECT address
	FROM address
	WHERE address_id = 3;

Ergebnis: 23 Workhaven Lane

Mithilfe des geschachtelten Befehls könntest Du letztere Abfragen in einer zusammenfassen. Das sähe so aus:

SELECT address
	FROM address
	WHERE address_id = (
		SELECT address_id
		FROM staff
		WHERE first_name = "Mike");

Ergebnis: 23 Workhaven Lane

Wird in der WHERE-Klausel der Hauptabfrage ein Vergleichsoperator verwendet, so darf die Unterabfrage nur einen einzigen Wert liefern, da der Vergleich sonst nicht ausführbar ist.

Beispiel:

Wir machen einen Fehler ...

SELECT address
	FROM address
	WHERE address_id = (
		SELECT address_id
		FROM staff
		WHERE active = 1);

Die Unterabfrage liefert mehrere Werte. Dies führt zu diesem unausführbaren Vergleich:

WHERE address_id = (3, 4)

"address_id" kann nur einen Wert annehmen, die innnere Abfrage liefert aber zwei Werte: 3 & 4.

Beispiel:

Und wir machen noch einen Fehler ...

SELECT address
	FROM address
	WHERE address_id = (
		SELECT address_id, store_id
		FROM staff
		WHERE active = 1);

Die Unterabfrage liefert mehrere Paare von Werten.

Dies führt zu diesem unausführbaren Vergleich:

WHERE address_id = ( ( 3, 1 ) ( 4, 2 ) )

"address_id" kann nur einen Wert annehmen, die innnere Abfrage liefert aber mehrere Wertepaare: 3; 1 & 4; 2.

Soll die Abfrage Werte als Liste liefern, so kann man den Vergleichsoperator " = " durch den IN-Operator ersetzen.

Beispiel:

Wir versuchen es ein letztes Mal ...

SELECT address
	FROM address
	WHERE address_id IN (
		SELECT address_id, store_id
		FROM staff
		WHERE active = 1);

Die Unterabfrage liefert eine Liste mit vergleichbaren Werten:

address_id IN (3, 4)
store_id IN (1, 2)

Es werden nur die Adressen ausgewählt, deren address_id sich in der Liste (3; 4) befindet.

Das Problem ist, dass mariaDB unterschiedliche Wertelisten für einen Wert noch nicht unterstützt. Stell Dir vor, dass die Unterabfrage zwei Listen zurück gibt, eine mit der Überschrift "address_id", die andere mit der Überschrift "store_id". MariaDB kann aber nur in eine Liste gleichzeitig reinschauen.

Möchtest Du die "adress_id" in beiden Listen suchen, kannst Du zum Beispiel nach der schließenden Klammer der Unterabfrage mithilfe von AND eine weitere Unterabfrage anhängen:

SELECT address
	FROM address
	WHERE address_id IN (
		SELECT address_id
		FROM staff
		WHERE active = 1)
	AND adress_id IN (
		SELECT store_id
		FROM staff
		WHERE active = 1);

Zusammenfassung:

  1. In der WHERE-Klausel der Hauptabfrage einer geschachtelten SELECT-Anweisung kann ein Vergleichsoperator oder der IN-Operator verwendet werden.

  2. Wenn ein Vergleichsoperator verwendet wird, darf die Unterabfrage nur einen einzigen Wert zurückgeben.

  3. Werden mehrere Werte einer einzigen Spalte vom inneren SELECT-Statement zurückgegeben, so muss der IN-Operator verwendet werden.