Subqueries: Unterschied zwischen den Versionen

Aus FI-Wiki
Keine Bearbeitungszusammenfassung
 
(36 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
== Subqueries in SQL ==
'''Subqueries''' (Unterabfragen) sind [[SQL]]-Abfragen, die innerhalb einer anderen Abfrage eingebettet sind. 
Sie liefern Zwischenergebnisse, die von der äußeren Abfrage weiterverarbeitet werden.


Subqueries (Unterabfragen) sind SQL-Abfragen, die innerhalb einer anderen Abfrage eingebettet sind. Sie liefern Zwischenergebnisse, die in der äußeren Abfrage verwendet werden.
== Arten von Subqueries ==
* '''Skalare Subquery''' – liefert genau '''einen Wert''' zurück 
* '''Mehrzeilige Subquery''' – liefert '''mehrere Werte''' (z. B. für IN)
* '''Korrelierte Subquery''' – bezieht sich auf die aktuelle Zeile der äußeren Abfrage


=== Arten von Subqueries ===
In diesem Abschnitt werden '''skalare Subqueries''' anhand von Beispielen erklärt.


* '''Skalare Subquery''': Gibt genau einen Wert zurück
== Beispieltabellen ==
* '''Mehrzeilige Subquery''': Gibt eine Liste von Werten zurück
* '''Korrelierte Subquery''': Bezieht sich auf eine Tabelle der äußeren Abfrage


=== Beispieltabellen ===
'''Tabelle: kunde'''
{| class="wikitable"
! kundennr !! name !! land
|-
| 1 || Anna || Deutschland
|-
| 2 || Ben || Deutschland
|-
| 3 || Clara || Österreich
|-
| 4 || David || Schweiz
|-
| 5 || Eva || Deutschland
|}


<syntaxhighlight lang="sql">
'''Tabelle: bestellung'''
-- Tabelle Kunde
{| class="wikitable"
CREATE TABLE kunde (
! bestellnr !! kundennr !! betrag
    kundennr INT PRIMARY KEY,
|-
    name VARCHAR(50),
| 101 || 1 || 900.00
    land VARCHAR(50)
|-
);
| 102 || 2 || 1500.00
 
|-
INSERT INTO kunde VALUES
| 103 || 3 || 500.00
(1, 'Anna', 'Deutschland'),
|-
(2, 'Ben', 'Deutschland'),
| 104 || 4 || 2200.00
(3, 'Clara', 'Österreich'),
|-
(4, 'David', 'Schweiz'),
| 105 || 2 || 300.00
(5, 'Eva', 'Deutschland');
|}


-- Tabelle Bestellung
== Skalare Subqueries ==
CREATE TABLE bestellung (
bestellnr INT PRIMARY KEY,
kundennr INT,
betrag DECIMAL(10,2),
FOREIGN KEY (kundennr) REFERENCES kunde(kundennr)
);


INSERT INTO bestellung VALUES
Skalare Subqueries liefern '''genau einen einzelnen Wert''' zurück 
(101, 1, 900.00),
(z. B. MAX, MIN, COUNT, AVG).
(102, 2, 1500.00),
(103, 3, 500.00),
(104, 4, 2200.00),
(105, 2, 300.00); </syntaxhighlight>


=== 1. Skalare Subquery ===
=== Skalare Subquery in der WHERE-Klausel ===


==== Kunde mit der höchsten Einzelbestellung ====
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT name
SELECT name
Zeile 54: Zeile 60:


'''Ergebnis:'''
'''Ergebnis:'''
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
name
name
Zeile 61: Zeile 66:
</syntaxhighlight>
</syntaxhighlight>


Gibt den Namen des Kunden mit der höchsten Bestellung zurück.
Die innere Subquery ermittelt den '''höchsten Bestellbetrag'''.


=== 2. Mehrzeilige Subquery mit IN ===


==== Kunde mit der kleinsten Einzelbestellung ====
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT name
SELECT name
FROM kunde
FROM kunde
WHERE kundennr IN (
WHERE kundennr = (
     SELECT kundennr
     SELECT kundennr
     FROM bestellung
     FROM bestellung
     WHERE betrag > 1000
     WHERE betrag = (SELECT MIN(betrag) FROM bestellung)
);
);
</syntaxhighlight>
</syntaxhighlight>


'''Ergebnis:'''
'''Ergebnis:'''
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
name
name
------
------
Ben
Ben
David
</syntaxhighlight>
</syntaxhighlight>


Gibt alle Kunden zurück, die Bestellungen über 1000 haben.
Die innere Subquery ermittelt den ''' niedrigsten Bestellbetrag '''.
 
=== 3. Korrelierte Subquery ===


==== Kunde mit dem höchsten Gesamtbestellwert ====
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT name
SELECT name
FROM kunde k
FROM kunde
WHERE EXISTS (
WHERE kundennr = (
     SELECT *
     SELECT kundennr
     FROM bestellung b
     FROM bestellung
     WHERE b.kundennr = k.kundennr AND b.betrag > 1000
     GROUP BY kundennr
    ORDER BY SUM(betrag) DESC
    LIMIT 1
);
);
</syntaxhighlight>
</syntaxhighlight>


'''Ergebnis:'''
'''Ergebnis:'''
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
name
name
------
------
Ben
Ben
David
</syntaxhighlight>
</syntaxhighlight>


Funktioniert zeilenweise: Gibt Kunden zurück, für die es mindestens eine große Bestellung gibt.
==== Skalare Subquery in der SELECT-Klausel ====
 
<syntaxhighlight lang="sql">
SELECT name,
(
    SELECT COUNT(*)
    FROM bestellung
    WHERE bestellung.kundennr = kunde.kundennr
) AS anzahl_bestellungen
FROM kunde;
</syntaxhighlight>
 
Diese Abfrage zeigt '''für jeden Kunden''' die Anzahl seiner Bestellungen.
 
==== Warum ist das eine korrelierte Subquery? ====
* Die Subquery greift auf die äußere Tabelle zu:
<syntaxhighlight lang="sql">
bestellung.kundennr = kunde.kundennr
</syntaxhighlight>
* Sie wird daher '''für jede Zeile der äußeren Abfrage neu ausgeführt'''
 


=== Vergleich der Subquery-Arten ===
=== Skalare Subquery in der HAVING-Klausel ===


* '''Skalare Subquery''': 1 Zeile, 1 Spalte (z. B. MAX, COUNT)
<syntaxhighlight lang="sql">
* '''Mehrzeilige Subquery''': mehrere Zeilen (z. B. für IN oder NOT IN)
SELECT kundennr
* '''Korrelierte Subquery''': wird für jede Zeile der äußeren Abfrage neu ausgeführt
FROM bestellung
GROUP BY kundennr
HAVING SUM(betrag) > (
    SELECT AVG(betrag)
    FROM bestellung
);
</syntaxhighlight>


=== Fazit ===
Gibt alle Kunden zurück, deren '''Bestellsumme über dem Durchschnitt''' liegt.


* Skalare Subquery: liefert genau einen Wert
=== Zusammenfassung ===
* Mehrzeilige Subquery: liefert eine Liste von Werten
* Subqueries sind Abfragen innerhalb von Abfragen 
* Korrelierte Subquery: ist abhängig von der äußeren Zeile und flexibler, aber ggf. langsamer
* Skalare Subqueries liefern genau '''einen Wert''' 
* Sie können in '''WHERE''', '''SELECT''' und '''HAVING''' verwendet werden 
* Korrelierte Subqueries beziehen sich auf die äußere Abfrage und laufen zeilenweise 


[[Kategorie:Datenbanken]]
[[Kategorie:Datenbanken]]
[[Kategorie:Semester2]]
[[Kategorie:Semester2]]

Aktuelle Version vom 11. Januar 2026, 12:20 Uhr

Subqueries (Unterabfragen) sind SQL-Abfragen, die innerhalb einer anderen Abfrage eingebettet sind. Sie liefern Zwischenergebnisse, die von der äußeren Abfrage weiterverarbeitet werden.

Arten von Subqueries

  • Skalare Subquery – liefert genau einen Wert zurück
  • Mehrzeilige Subquery – liefert mehrere Werte (z. B. für IN)
  • Korrelierte Subquery – bezieht sich auf die aktuelle Zeile der äußeren Abfrage

In diesem Abschnitt werden skalare Subqueries anhand von Beispielen erklärt.

Beispieltabellen

Tabelle: kunde

kundennr name land
1 Anna Deutschland
2 Ben Deutschland
3 Clara Österreich
4 David Schweiz
5 Eva Deutschland

Tabelle: bestellung

bestellnr kundennr betrag
101 1 900.00
102 2 1500.00
103 3 500.00
104 4 2200.00
105 2 300.00

Skalare Subqueries

Skalare Subqueries liefern genau einen einzelnen Wert zurück (z. B. MAX, MIN, COUNT, AVG).

Skalare Subquery in der WHERE-Klausel

Kunde mit der höchsten Einzelbestellung

SELECT name
FROM kunde
WHERE kundennr = (
    SELECT kundennr
    FROM bestellung
    WHERE betrag = (SELECT MAX(betrag) FROM bestellung)
);

Ergebnis:

name
------
David

Die innere Subquery ermittelt den höchsten Bestellbetrag.


Kunde mit der kleinsten Einzelbestellung

SELECT name
FROM kunde
WHERE kundennr = (
    SELECT kundennr
    FROM bestellung
    WHERE betrag = (SELECT MIN(betrag) FROM bestellung)
);

Ergebnis:

name
------
Ben

Die innere Subquery ermittelt den niedrigsten Bestellbetrag .

Kunde mit dem höchsten Gesamtbestellwert

SELECT name
FROM kunde
WHERE kundennr = (
    SELECT kundennr
    FROM bestellung
    GROUP BY kundennr
    ORDER BY SUM(betrag) DESC
    LIMIT 1
);

Ergebnis:

name
------
Ben

Skalare Subquery in der SELECT-Klausel

SELECT name,
(
    SELECT COUNT(*)
    FROM bestellung
    WHERE bestellung.kundennr = kunde.kundennr
) AS anzahl_bestellungen
FROM kunde;

Diese Abfrage zeigt für jeden Kunden die Anzahl seiner Bestellungen.

Warum ist das eine korrelierte Subquery?

  • Die Subquery greift auf die äußere Tabelle zu:
bestellung.kundennr = kunde.kundennr
  • Sie wird daher für jede Zeile der äußeren Abfrage neu ausgeführt


Skalare Subquery in der HAVING-Klausel

SELECT kundennr
FROM bestellung
GROUP BY kundennr
HAVING SUM(betrag) > (
    SELECT AVG(betrag)
    FROM bestellung
);

Gibt alle Kunden zurück, deren Bestellsumme über dem Durchschnitt liegt.

Zusammenfassung

  • Subqueries sind Abfragen innerhalb von Abfragen
  • Skalare Subqueries liefern genau einen Wert
  • Sie können in WHERE, SELECT und HAVING verwendet werden
  • Korrelierte Subqueries beziehen sich auf die äußere Abfrage und laufen zeilenweise