Direkt zum Hauptinhalt springen
eLearner.app
Modul 7 · Lektion 1 von 425/57 im Kurs~12 min
Lektionen des Moduls (1/4)

CTE: Mehrstufige Abfragen mit WITH

Echte Abfragen nehmen tendenziell zu: drei JOINs, ein GROUP BY, eine Unterabfrage, eine weitere Unterabfrage ... und sie werden unlesbar. CTEs ("Common Table Mit „Ausdrücken“, der WITH-Klausel) können Sie einem einen Namen geben Zwischenschritt und verwenden Sie ihn so, als wäre er eine Tabelle in der Hauptabfrage.

Grundlegende Syntax

SQL
WITH nome_cte AS (
  SELECT-- query interna
)
SELECT-- query principale, usa nome_cte come fosse una tabella
FROM   nome_cte;

Ein CTE ist nur für die darauf folgende Abfrage gültig: Er bleibt nicht bestehen die Ausführung.

Beispiel

Finden Sie die 3 Kunden, die am meisten ausgegeben haben (Summe der gelieferten Bestellungen):

SQL
WITH total_spent AS (
  SELECT o.customer_id,
         SUM(oi.quantity * oi.unit_price) AS total
  FROM   orders      o
  JOIN   order_items oi ON oi.order_id = o.id
  WHERE  o.status = 'delivered'
  GROUP BY o.customer_id
)
SELECT c.email,
       s.total
FROM   total_spent s
JOIN   customers c ON c.id = s.customer_id
ORDER BY s.total DESC
LIMIT  3;

Lesen Sie auf Englisch: _ „Berechnen Sie zuerst die Ausgaben pro Kunde und schließen Sie sich dann an.“ Kunden und holen Sie sich die Top 3"_. Ohne einen CTE bräuchten Sie einen Inline Unterabfrage im FROM (legal, aber lauter).

Mehrere CTEs in Kaskade

Sie können mehrere durch Kommas getrennte CTEs definieren, auf die jeweils verwiesen werden kann zu den vorherigen:

SQL
WITH total_spent AS (
  SELECT customer_id, SUM(quantity * unit_price) AS total
  FROM   order_items oi
  JOIN   orders      o ON oi.order_id = o.id
  WHERE  o.status = 'delivered'
  GROUP BY customer_id
),
average AS (
  SELECT AVG(total) AS total_average
  FROM   total_spent
)
SELECT c.email, s.total
FROM   total_spent s
JOIN   customers c ON c.id = s.customer_id
CROSS JOIN average
WHERE  s.total > average.total_average
ORDER BY s.total DESC;

CROSS JOIN average, weil average immer eine einzelne Zeile hat: die Das kartesische Produkt hängt einfach total_average an jede Zeile des Ergebnisses an.

CTE vs. Unterabfrage: Wann welche verwenden

CTEs glänzen, wenn:

  • Dieselbe Unterabfrage wird in der Hauptabfrage zwei- oder mehrmals verwendet.
  • Sie möchten die Struktur in benannten Schritten explizit machen (selbstdokumentierend);
  • Sie sind die Voraussetzung für rekursive CTEs (WITH RECURSIVE, nächste Lektion in diesem Modul).

Eine Inline-Unterabfrage ist prägnanter für einen Schritt, der nur einmal verwendet wird.

Probieren Sie es aus

Übung#sql.m7.l1.e1
Versuche: 0Wird geladen…

Verwenden Sie einen CTE namens „total_spent“, der für jeden Kunden die Gesamtausgaben (SUM(quantity * unit_price)) für gelieferte Bestellungen berechnet. Zeigen Sie dann in der Hauptabfrage die E-Mail-Adresse und die Gesamtsumme für die drei größten Geldgeber an. Sortierung nach absteigender Summe, Begrenzung auf 3.

Editor wird geladen…
Hinweis anzeigen

Innerhalb der CTE-Summe Menge * Einheitspreis. In der Hauptabfrage JOIN-Kunden mit der ID.

Lösung nach 3 Versuchen verfügbar

Wiederholungsübung

Übung#sql.m7.l1.e2
Versuche: 0Wird geladen…

Gleicher CTE „total_spent“ wie in der vorherigen Übung. In der Hauptabfrage werden die E-Mail-Adresse und die Gesamtsumme der Kunden angezeigt, deren Ausgaben über den durchschnittlichen Ausgaben liegen (für alle Kunden mit mindestens einer gelieferten Bestellung). Sortierung nach absteigender Summe.

Editor wird geladen…
Hinweis anzeigen

Skalare Unterabfrage im WHERE: SELECT AVG(total) FROM total_spent.

Lösung nach 3 Versuchen verfügbar