Die aktuellste Zeile je Schlüssel beibehalten
Das Muster „aktuellster Datensatz je Kunde“ mit Partitionierung nach Schlüssel und Sortierung nach Datum
Die aktuellste Zeile je Schlüssel beibehalten 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.
Die Frage nach der aktuellsten Zeile pro Schlüssel
„Geben Sie die aktuellste Bestellung für jeden Kunden zurück.“ „Ermitteln Sie den neuesten Status für jedes Gerät.“ Dieses Problem der aktuellsten Zeile pro Schlüssel gehört zu den häufigsten SQL-Aufgaben in Vorstellungsgesprächen, da es in der praktischen Analysearbeit ständig vorkommt.
Es handelt sich um eine spezialisierte Variante des Top-1-pro-Gruppe-Problems: Partitionieren Sie nach dem Schlüssel, sortieren Sie nach dem Zeitstempel absteigend und behalten Sie die erste Zeile bei. In dieser Lektion lernen Sie das Muster und seine Alternativen gründlich kennen.
Warum MAX allein nicht ausreicht
Eine zunächst naheliegende Antwort ist MAX(order_date), gruppiert nach dem Kunden. Das liefert das aktuellste Datum, aber nicht den Rest der zugehörigen Bestellung, etwa Bestell-ID, Betrag oder Status.
Wenn die interviewende Person die vollständige aktuellste Zeile erwartet, benötigt MAX mit GROUP BY eine zusätzliche Verknüpfung mit der Tabelle über den Schlüssel und das maximale Datum. Das ist umfangreich und kann bei Gleichständen scheitern. Fensterfunktionen sind übersichtlicher.
-- Gives the date, not the full row
SELECT customer_id, MAX(order_date) AS last_order
FROM orders
GROUP BY customer_id;Das ROW_NUMBER-Muster
Partitionieren Sie nach dem Schlüssel und sortieren Sie nach dem Zeitstempel absteigend; dadurch erhält die aktuellste Zeile rn = 1. Behalten Sie nur diese Zeilen bei, und Sie erhalten den vollständigen aktuellsten Datensatz pro Schlüssel.
Das ist die Standardantwort. Sie gibt genau eine Zeile pro Schlüssel zurück, selbst wenn Zeitstempel gleich sind, was mit „der aktuellsten Zeile“ normalerweise gemeint ist.
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC
) AS rn
FROM orders
)
SELECT customer_id, order_id, order_date, amount
FROM ranked
WHERE rn = 1;Gleichstände bei Zeitstempeln auflösen
Zwei Bestellungen desselben Kunden können dasselbe order_date haben, etwa am selben Tag oder aufgrund identischer Zeitstempel. Ohne Tie-Breaker ist die Auswahl der Zeile mit rn = 1 beliebig und kann sich zwischen Ausführungen ändern.
Fügen Sie einen eindeutigen sekundären Schlüssel wie order_id DESC hinzu, damit die aktuellste Zeile deterministisch bestimmt wird. Interviewende prüfen ausdrücklich, ob Sie diesen Sonderfall erkannt haben.
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC, order_id DESC
) AS rnAktuellste Zeile oder alle Gleichstände
Entscheiden Sie, was „aktuellste“ bedeutet, wenn Zeitstempel gleich sind:
- Wenn Sie genau eine Zeile pro Schlüssel möchten → verwenden Sie
ROW_NUMBERmit einem Tie-Breaker. - Wenn Sie alle Zeilen möchten, die denselben maximalen Zeitstempel haben → verwenden Sie stattdessen
RANK() = 1, wodurch jede aktuellste Zeile mit Gleichstand zurückgegeben wird.
Mit dieser klärenden Frage zeigen Sie, dass Sie die Bedeutung und nicht nur die Syntax verstehen.
WITH ranked AS (
SELECT *,
RANK() OVER (
PARTITION BY customer_id ORDER BY order_date DESC
) AS rnk
FROM orders
)
SELECT * FROM ranked WHERE rnk = 1;Die Alternative mit korrelierter Unterabfrage
Bevor Fensterfunktionen allgemein verfügbar waren, wurde die aktuellste Zeile pro Schlüssel mithilfe einer korrelierten Unterabfrage ermittelt: Eine Zeile wird nur beibehalten, wenn keine andere Zeile für denselben Schlüssel ein späteres Datum hat.
Das funktioniert, führt die innere Abfrage jedoch für jede Zeile aus und ist daher bei großen Tabellen langsamer sowie bei Gleichständen umständlich. Erwähnen Sie diese Variante, um Ihre Kenntnisse zu zeigen, bevorzugen Sie aus Performancegründen aber die Lösung mit Fensterfunktion.
SELECT o.*
FROM orders o
WHERE o.order_date = (
SELECT MAX(o2.order_date)
FROM orders o2
WHERE o2.customer_id = o.customer_id
);Postgres: Abkürzung mit DISTINCT ON
PostgreSQL bietet ein kompaktes Muster: DISTINCT ON (key) behält gemäß dem ORDER BY die erste Zeile pro Schlüssel bei. Das ORDER BY muss mit denselben Schlüsselspalten beginnen, gefolgt von Tie-Breaker und Zeitstempel.
Das ist in Postgres elegant und schnell, aber nicht portabel. Erwähnen Sie es als dialektspezifischen Bonus, behalten Sie ROW_NUMBER jedoch als portable Standardlösung bei.
SELECT DISTINCT ON (customer_id)
customer_id, order_id, order_date, amount
FROM orders
ORDER BY customer_id, order_date DESC, order_id DESC;Aktuellste Zeile mit Bedingung
In realistischen Aufgaben kommen zusätzliche Filter hinzu: „die aktuellste abgeschlossene Bestellung pro Kunde“. Wenden Sie den Filter vor dem Ranking an, damit nur passende Zeilen nummeriert werden.
Setzen Sie die Bedingung in das WHERE der inneren Abfrage (sie wird vor der Fensterfunktion ausgeführt), und wählen Sie dann in der äußeren Abfrage rn = 1. Wenn Sie erst nach dem Ranking filtern, erhalten Sie die falsche Zeile.
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id ORDER BY order_date DESC, order_id DESC
) AS rn
FROM orders
WHERE status = 'completed'
)
SELECT * FROM ranked WHERE rn = 1;Durchgearbeitetes Beispiel: Aktueller Gerätestatus
Eine Tabelle namens status_log protokolliert device_id, status und logged_at. Um den aktuellen Status jedes Geräts zu ermitteln, partitionieren Sie nach device_id, sortieren Sie nach logged_at DESC und behalten Sie rn = 1 bei.
Das ist die Grundlage für Dashboards, die den „aktuellen Zustand“ vieler Entitäten aus einem Append-only-Ereignisprotokoll anzeigen. Dasselbe Muster ermöglicht Abfragen zum aktuellsten Preis, Standort und zur aktuellsten Version.
WITH latest AS (
SELECT device_id, status, logged_at,
ROW_NUMBER() OVER (
PARTITION BY device_id ORDER BY logged_at DESC
) AS rn
FROM status_log
)
SELECT device_id, status, logged_at
FROM latest
WHERE rn = 1;Hinweise zur Leistung
Diese Punkte zeigen Senior-Niveau:
- Ein Index auf
(customer_id, order_date DESC)ermöglicht es der Engine, die aktuellste Zeile pro Schlüssel effizient zu lesen. - Der Fensteransatz durchsucht die Tabelle einmal; die korrelierte Unterabfrage tut das nicht.
DISTINCT ONin Postgres kann denselben Index verwenden und ist häufig die schnellste Option für eine einzelne Tabelle.- Erwägen Sie bei Ereignisprotokollen mit überwiegend neuen Einträgen eine materialisierte „latest“-Tabelle, die inkrementell aktualisiert wird.
Häufige Fehler
Achten Sie auf Folgendes:
- Verwenden von
MAX(date)und Zurückgeben nur des Datums statt der vollständigen Zeile. - Vergessen des Tie-Breakers, wodurch bei gleichen Datumswerten nichtdeterministische Ergebnisse entstehen.
- Filtern nach der Bedingung erst nach dem Ranking, wodurch eine Zeile ausgewählt werden kann, die hätte ausgeschlossen werden müssen.
- Verwechseln von „der aktuellsten einzelnen Zeile“ (
ROW_NUMBER) mit „allen aktuellsten Zeilen mit Gleichstand“ (RANK).
Kurztest
Wählen Sie die richtige Abfrage für die aktuellste Zeile pro Schlüssel aus.
Rückblick: Aktuellste Zeile pro Schlüssel
Das Muster: PARTITION BY key, ORDER BY timestamp DESC (plus eindeutiger Tie-Breaker), rn = 1 beibehalten.
MAX(date)liefert das Datum, nicht die vollständige Zeile.- Fügen Sie immer einen Tie-Breaker hinzu, um deterministische Ergebnisse zu gewährleisten.
- Verwenden Sie
RANK() = 1, wenn Sie alle Zeilen mit dem aktuellsten Zeitstempel und Gleichstand möchten. - Filterbedingungen gehören in die innere Abfrage, vor das Ranking.
- Postgres
DISTINCT ONist eine kompakte, schnelle und dialektspezifische Alternative.
Häufig gestellte Fragen
Ist die Lektion „Die aktuellste Zeile je Schlüssel beibehalten“ kostenlos?
Ja — der vollständige Text von „Die aktuellste Zeile je Schlüssel beibehalten“ 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 „Die aktuellste Zeile je Schlüssel beibehalten“?
Das Muster „aktuellster Datensatz je Kunde“ mit Partitionierung nach Schlüssel und Sortierung nach Datum 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 „Die aktuellste Zeile je Schlüssel beibehalten“?
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
- Die obersten N Zeilen je Gruppe mit ROW_NUMBER
- Gleichstände bei den obersten N Werten behandeln
- Zeilen sicher deduplizieren
- Die aktuellste Zeile je Schlüssel beibehalten