Nach einem Fensterergebnis filtern
Warum Sie eine Fensterfunktion in eine Unterabfrage oder CTE einschließen müssen, um danach zu filtern
Nach einem Fensterergebnis filtern ist eine kostenlose SQL Interview Prep-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des SQL Interview Prep-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der SQL Interview Prep-Kurs umfasst insgesamt 4 Lektionen.
Warum Sie ein Fensterergebnis nicht in WHERE filtern können
Ein häufiger Fallstrick in Vorstellungsgesprächen: WHERE ROW_NUMBER() OVER (...) = 1 führt zu einem Fehler. Fensterfunktionen sind in WHERE, GROUP BY oder HAVING nicht erlaubt.
Der Grund ist die logische Ausführungsreihenfolge. WHERE wird ausgeführt, um Zeilen auszuwählen, bevor Fensterfunktionen ausgewertet werden. Das Fenster wurde zu diesem Zeitpunkt noch gar nicht berechnet und kann daher nicht in einem Filter verwendet werden.
Die Erklärung der Ausführungsreihenfolge
Fensterfunktionen werden in einer eigenen Phase berechnet. Diese liegt nach FROM, WHERE, GROUP BY und HAVING, aber vor dem abschließenden ORDER BY und LIMIT.
Wenn WHERE ausgeführt wird, existieren der Rang oder die Zeilennummer also noch nicht. Um danach zu filtern, müssen Sie zunächst die Berechnung des Fensters abschließen und anschließend die erzeugte Spalte in einer äußeren Abfrageebene filtern.
Das Muster mit einer Unterabfrage
Die übliche Lösung: Berechnen Sie die Fensterfunktion in einer inneren Abfrage (einer abgeleiteten Tabelle), vergeben Sie dem Ergebnis einen Alias und filtern Sie anschließend in der äußeren WHERE-Klausel nach diesem Alias.
Die abgeleitete Tabelle muss einen Alias haben (hier t) – Interviewer achten darauf, ob Kandidaten ihn vergessen. rn ist nun eine gewöhnliche Spalte, mit der die äußere Abfrage vergleichen kann.
SELECT *
FROM (
SELECT
name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
FROM employees
) t
WHERE rn = 1;Das CTE-Muster (oft übersichtlicher)
Eine Common Table Expression erledigt dieselbe Aufgabe mit einer besser lesbaren Struktur. Definieren Sie das Ranking in einem WITH-Schritt und filtern Sie es anschließend in der Hauptabfrage.
Funktional ist dies identisch mit der Unterabfrage. Beim Live-Coding bevorzugen Interviewer jedoch meist CTEs, weil die Absicht von oben nach unten lesbar ist.
WITH ranked AS (
SELECT
name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
FROM employees
)
SELECT name, department, salary
FROM ranked
WHERE rn = 1;Durchgearbeitetes Beispiel: Top-N pro Gruppe
Das häufigste Fensterproblem: „Die drei Mitarbeiter mit dem höchsten Gehalt pro Abteilung.“ Führen Sie das Ranking in der CTE durch und behalten Sie anschließend außerhalb der CTE rn <= 3.
Wählen Sie die Ranking-Funktion abhängig vom gewünschten Verhalten bei Gleichständen: ROW_NUMBER begrenzt jede Abteilung auf genau drei Zeilen. Wechseln Sie zu RANK/DENSE_RANK, wenn Gleichstände an der Grenze eingeschlossen werden müssen.
WITH ranked AS (
SELECT department, name, salary,
ROW_NUMBER() OVER (
PARTITION BY department ORDER BY salary DESC
) AS rn
FROM employees
)
SELECT department, name, salary
FROM ranked
WHERE rn <= 3
ORDER BY department, rn;Durchgearbeitetes Beispiel: Filtern nach einer laufenden Summe
Das Wrapper-Muster gilt nicht nur für Ränge. Jedes Fensterergebnis – laufende Summen, gleitende Durchschnitte, LAG-Differenzen – muss auf dieselbe Weise gefiltert werden.
Hier berechnen wir einen laufenden Kontostand und behalten anschließend nur die Zeilen, in denen er erstmals 1000 überschreitet. Der Filter befindet sich außerhalb der Fensterebene.
WITH balances AS (
SELECT
account_id, txn_date, amount,
SUM(amount) OVER (
PARTITION BY account_id ORDER BY txn_date
) AS running_balance
FROM transactions
)
SELECT *
FROM balances
WHERE running_balance > 1000;QUALIFY: Die Abkürzung in einigen Datenbanken
Snowflake, BigQuery, Teradata und DuckDB bieten eine QUALIFY-Klausel, mit der Fensterergebnisse direkt gefiltert werden können – ganz ohne Wrapper. Sie wird nach den Fensterfunktionen ausgeführt, also genau an der gewünschten Stelle.
Erwähnen Sie QUALIFY, um Ihre Kenntnisse zu zeigen, weisen Sie aber darauf hin, dass es kein Standard-SQL ist und in PostgreSQL, MySQL und SQL Server fehlt. Dort benötigen Sie weiterhin die Unterabfrage oder CTE.
-- Snowflake / BigQuery only:
SELECT department, name, salary
FROM employees
QUALIFY ROW_NUMBER() OVER (
PARTITION BY department ORDER BY salary DESC
) = 1;Verwechseln Sie HAVING nicht mit dem Filtern von Fensterergebnissen
Manche Kandidaten versuchen, einen Rang mit HAVING zu filtern. HAVING filtert Gruppen nach der Aggregation durch GROUP BY und wird weiterhin vor den Fensterfunktionen ausgeführt. Daher kann es ebenfalls nicht auf eine Fensterspalte verweisen.
WHERE→ filtert Zeilen vor der Gruppierung und vor den Fenstern.HAVING→ filtert aggregierte Gruppen, ebenfalls vor den Fenstern.- Fensterergebnisse filtern → erfordert eine äußere Abfrage (oder
QUALIFY).
Vorfilter mit einem Fensterfilter kombinieren
Oft filtern Sie sowohl vor als auch nach dem Fenster. Wenden Sie gewöhnliche Zeilenfilter in der inneren WHERE-Klausel an, damit das Fenster nur relevante Zeilen sieht. Filtern Sie das Fensterergebnis anschließend in der äußeren Abfrage.
In diesem Beispiel schränken wir zunächst auf aktive Mitarbeiter ein und wählen dann unter ihnen den Spitzenverdiener jeder Abteilung aus. Wenn Sie WHERE active in die innere Abfrage setzen, verändert dies die Zeilen, über die das Ranking gebildet wird.
WITH ranked AS (
SELECT department, name, salary,
ROW_NUMBER() OVER (
PARTITION BY department ORDER BY salary DESC
) AS rn
FROM employees
WHERE is_active = true -- pre-filter before ranking
)
SELECT * FROM ranked
WHERE rn = 1; -- post-filter on the windowHinweis zur Performance
Interviewer fragen möglicherweise, ob der Wrapper die Performance beeinträchtigt. Normalerweise nicht: Der Optimierer behandelt die Unterabfrage oder CTE als Teil eines einzigen Ausführungsplans und berechnet das Fenster nur einmal. Nur weil Sie die Abfrage in einen Wrapper einschließen, gibt es keinen zusätzlichen Scan.
Ein Vorbehalt: In einigen Engines kann eine CTE eine Optimierungsschranke darstellen und materialisiert werden. Für besonders häufig ausgeführte Abfragen kann daher eine abgeleitete Tabelle oder QUALIFY einen besseren Plan ergeben. Verwenden Sie EXPLAIN, wenn dies relevant ist.
Häufige Fehler
Abschließende Checkliste:
- Verwenden Sie niemals eine Fensterfunktion in
WHERE/HAVING– dies führt zu einem Fehler. - Vergeben Sie immer einen Alias für die abgeleitete Tabelle; eine nicht benannte Unterabfrage in
FROMwird abgelehnt. - Wählen Sie die Ranking-Funktion passend zum benötigten Verhalten bei Gleichständen.
- Verwenden Sie
QUALIFYnur dort, wo es unterstützt wird. Andernfalls greifen Sie auf den CTE- oder Unterabfrage-Wrapper zurück.
Kurze Überprüfung
Warum erfordert das Filtern einer Fensterfunktion einen Wrapper?
Zusammenfassung: Fensterergebnisse filtern
Sie haben den vollständigen Ablauf beim Filtern von Ranking-Fensterfunktionen kennengelernt:
- Fensterfunktionen werden nach
WHERE/GROUP BY/HAVINGausgeführt. Daher können Sie sie dort nicht filtern. - Schließen Sie das Fenster in eine Unterabfrage oder CTE ein (immer mit Alias) und filtern Sie das Ergebnis in der äußeren Abfrage.
- Dieses Muster ermöglicht Top-N pro Gruppe, die jeweils aktuellste Zeile pro Schlüssel und Schwellenwerte für laufende Summen.
QUALIFYist eine praktische nicht standardisierte Abkürzung, die nur in Snowflake und BigQuery verfügbar ist.
Damit verfügen Sie über das vollständige Ranking-Werkzeug, das Interviewer am häufigsten prüfen.
Häufig gestellte Fragen
Ist die Lektion „Nach einem Fensterergebnis filtern“ kostenlos?
Ja — der vollständige Text von „Nach einem Fensterergebnis filtern“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des SQL Interview Prep-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der SQL Interview Prep-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Nach einem Fensterergebnis filtern“?
Warum Sie eine Fensterfunktion in eine Unterabfrage oder CTE einschließen müssen, um danach zu filtern Du übst SQL Interview Prep mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um SQL Interview Prep zu starten?
Keine Vorkenntnisse erforderlich. SQL Interview Prep auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Nach einem Fensterergebnis filtern“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser SQL Interview Prep-Lektion Code schreiben und ausführen?
Ja. Jede SQL Interview Prep-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- OVER, PARTITION BY und ORDER BY
- ROW_NUMBER für eine eindeutige Reihenfolge
- RANK oder DENSE_RANK bei Gleichständen
- Nach einem Fensterergebnis filtern