De nieuwste rij per sleutel behouden
Het patroon 'meest recente record per klant' met partitioneren op sleutel en ordenen op datum
De nieuwste rij per sleutel behouden is een gratis Voorbereiding op programmeerinterviews-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Voorbereiding op programmeerinterviews. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Voorbereiding op programmeerinterviews bevat in totaal 4 lessen.
De vraag naar de meest recente rij per sleutel
"Geef de meest recente bestelling voor elke klant terug." "Geef de nieuwste status voor elk apparaat." Dit probleem van de meest recente rij per sleutel is een van de meest voorkomende SQL-opdrachten tijdens sollicitatiegesprekken, omdat het voortdurend voorkomt in echt analytisch werk.
Het is een gespecialiseerde top-1-per-groep: partitioneer op de sleutel, sorteer de tijdstempel aflopend en behoud de eerste rij. In deze les oefen je dit patroon en de alternatieven.
Waarom MAX alleen niet volstaat
Een verleidelijk eerste antwoord is MAX(order_date), gegroepeerd per klant. Dat geeft de nieuwste datum, maar niet de rest van de rij van die bestelling, het bestel-id, het bedrag of de status.
Als de interviewer de volledige nieuwste rij wil, heb je bij MAX met GROUP BY een extra join terug naar de tabel nodig op de sleutel en de maximale datum. Dat is langdradig en kan bij gelijke waarden misgaan. Vensterfuncties zijn overzichtelijker.
-- Gives the date, not the full row
SELECT customer_id, MAX(order_date) AS last_order
FROM orders
GROUP BY customer_id;Het ROW_NUMBER-patroon
Partitioneer op de sleutel, sorteer de tijdstempel aflopend en de nieuwste rij krijgt rn = 1. Behoud alleen die rijen en je hebt het volledige meest recente record per sleutel.
Dit is het standaardantwoord. Het levert precies één rij per sleutel op, zelfs wanneer tijdstempels gelijk zijn, wat meestal wordt bedoeld met "de nieuwste rij".
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;Gelijke tijdstempels onderscheiden
Twee bestellingen van dezelfde klant kunnen dezelfde order_date hebben, bijvoorbeeld op dezelfde dag of met identieke tijdstempels. Zonder een secundaire sorteersleutel is het willekeurig welke rij rn = 1 wordt en kan dit per uitvoering verschillen.
Voeg een unieke secundaire sleutel toe, zoals order_id DESC, zodat de nieuwste rij altijd bepaald is. Interviewers toetsen specifiek of je dit randgeval hebt opgemerkt.
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC, order_id DESC
) AS rnNieuwste rij of alle gelijke waarden
Bepaal wat "nieuwste" betekent wanneer tijdstempels gelijk zijn:
- Wil je precies één rij per sleutel → gebruik
ROW_NUMBERmet een secundaire sorteersleutel. - Wil je alle rijen met de maximale tijdstempel → gebruik dan
RANK() = 1, waarmee elke gelijke nieuwste rij wordt teruggegeven.
Door deze verduidelijkende vraag te stellen, laat je zien dat je de betekenis begrijpt en niet alleen de syntaxis.
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;Het alternatief met een gecorreleerde subquery
Voordat vensterfuncties algemeen beschikbaar waren, werd het antwoord voor de nieuwste rij per sleutel gegeven met een gecorreleerde subquery: behoud een rij alleen als geen andere rij voor dezelfde sleutel een latere datum heeft.
Dit werkt, maar voert de binnenquery voor elke rij uit. Daardoor is het trager bij grote tabellen en onhandig bij gelijke waarden. Noem het om je brede kennis te tonen, maar geef voor betere prestaties de voorkeur aan het antwoord met vensterfuncties.
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-snelkoppeling met DISTINCT ON
Postgres biedt een beknopte constructie: DISTINCT ON (key) behoudt de eerste rij per sleutel volgens de ORDER BY. De ORDER BY moet beginnen met dezelfde sleutelkolommen, gevolgd door de secundaire sorteersleutel of tijdstempel.
Dit is elegant en snel in Postgres, maar niet database-onafhankelijk. Noem het als bonus voor een specifiek dialect, maar houd ROW_NUMBER als je standaardkeuze voor draagbare code.
SELECT DISTINCT ON (customer_id)
customer_id, order_id, order_date, amount
FROM orders
ORDER BY customer_id, order_date DESC, order_id DESC;Nieuwste rij met een voorwaarde
In echte vragen komen filters voor: "de meest recente voltooide bestelling per klant". Pas het filter toe voordat je rangschikt, zodat alleen rijen die aan de voorwaarde voldoen een nummer krijgen.
Zet de voorwaarde in de WHERE van de binnenquery, die vóór de vensterfunctie wordt uitgevoerd, en neem daarna rn = 1 in de buitenquery. Als je na het rangschikken filtert, krijg je de verkeerde rij.
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;Uitgewerkt voorbeeld: nieuwste apparaatstatus
Een tabel status_log registreert device_id, status en logged_at. Om de huidige status van elk apparaat te krijgen, partitioneer je op device_id, sorteer je op logged_at DESC en behoud je rn = 1.
Dit is de motor achter dashboards die de "huidige toestand" van veel entiteiten tonen vanuit een gebeurtenislogboek waaraan alleen nieuwe gebeurtenissen worden toegevoegd. Hetzelfde recept werkt voor query's naar de nieuwste prijs, locatie en versie.
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;Opmerkingen over prestaties
Bespreekpunten waarmee je waardering op seniorniveau verdient:
- Met een index op
(customer_id, order_date DESC)kan de databasemotor de nieuwste rij per sleutel efficiënt lezen. - De vensterbenadering scant de tabel één keer; de gecorreleerde subquery doet dat niet.
DISTINCT ONin Postgres kan dezelfde index gebruiken en is vaak de snelste optie voor één tabel.- Overweeg voor gebeurtenislogboeken met veel toevoegingen een gematerialiseerde tabel met de "nieuwste" waarde die stapsgewijs wordt vernieuwd.
Veelgemaakte fouten
Let op het volgende:
MAX(date)gebruiken en alleen de datum teruggeven, niet de volledige rij.- De secundaire sorteersleutel vergeten, waardoor bij gelijke datums niet-deterministische resultaten ontstaan.
- De voorwaarde na het rangschikken toepassen, waardoor je een rij kunt kiezen die uitgesloten had moeten worden.
- "één nieuwste rij" (
ROW_NUMBER) verwarren met "alle nieuwste rijen bij gelijke waarden" (RANK).
Snelle controle
Kies de juiste query voor de nieuwste rij per sleutel.
Samenvatting: nieuwste rij per sleutel
Het patroon: PARTITION BY key, ORDER BY timestamp DESC (plus een unieke secundaire sorteersleutel), behoud rn = 1.
MAX(date)geeft de datum, niet de volledige rij.- Voeg altijd een secundaire sorteersleutel toe voor deterministische resultaten.
- Gebruik
RANK() = 1als je alle rijen wilt die dezelfde nieuwste tijdstempel hebben. - Voorwaarden horen in de binnenquery, vóór het rangschikken.
- Postgres
DISTINCT ONis een beknopt en snel alternatief voor een specifiek dialect.
Leer Voorbereiding op programmeerinterviews met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 90
- Lessen
- 360
Veelgestelde vragen
Is de les “De nieuwste rij per sleutel behouden” gratis?
Ja — de volledige tekst van “De nieuwste rij per sleutel behouden” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Voorbereiding op programmeerinterviews wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Voorbereiding op programmeerinterviews bevat in totaal 4 lessen.
Wat leer ik in “De nieuwste rij per sleutel behouden”?
Het patroon 'meest recente record per klant' met partitioneren op sleutel en ordenen op datum Je oefent met Voorbereiding op programmeerinterviews door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Voorbereiding op programmeerinterviews te beginnen?
Ervaring vooraf is niet nodig. Voorbereiding op programmeerinterviews op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “De nieuwste rij per sleutel behouden”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Voorbereiding op programmeerinterviews?
Ja. Elke les over Voorbereiding op programmeerinterviews bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Top-N-rijen per groep met ROW_NUMBER
- Gelijke waarden in Top-N-resultaten afhandelen
- Rijen veilig ontdubbelen
- De nieuwste rij per sleutel behouden