ROW_NUMBER til entydig sekvensering
Tildel et deterministisk rækkenummer inden for hver partition
ROW_NUMBER til entydig sekvensering er en gratis Forberedelse til kodeinterviews-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Forberedelse til kodeinterviews, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Forberedelse til kodeinterviews-kurset indeholder 4 lektioner i alt.
Hvad ROW_NUMBER garanterer
ROW_NUMBER() tildeler hvert række i sin partition et unikt heltal uden huller, begyndende med 1 og efter vinduets ORDER BY. Ingen to rækker får nogensinde samme nummer, heller ikke når deres sorteringsværdier er identiske.
Denne entydighed er netop grunden til, at interviewere vælger den til problemer, hvor man skal "vælge én række pr. gruppe", eller til fjernelse af dubletter. De andre rangeringsfunktioner, RANK og DENSE_RANK, lover ikke entydighed ved ens værdier.
Minimal ROW_NUMBER-forespørgsel
Den enkleste form nummererer et helt resultatsæt i en valgt rækkefølge. ROW_NUMBER kræver altid en ORDER BY inde i OVER — uden den ville nummereringen være vilkårlig, og de fleste databasemotorer afviser den eller udsender en advarsel.
Her er den medarbejder, der senest blev ansat, række 1, hvis du sorterer efter ansættelsesdato i faldende rækkefølge.
SELECT
name,
hire_date,
ROW_NUMBER() OVER (ORDER BY hire_date DESC) AS rn
FROM employees;Nummerering inden for partitioner
Tilføj PARTITION BY for at nummerere rækker uafhængigt i hver gruppe. Tælleren nulstilles ved hver ny partitionsværdi.
I eksemplet får hver afdeling sin egen sekvens med 1, 2, 3, sorteret efter løn. Den højest lønnede i hver afdeling får nummer 1 — grundlaget for mønsteret top-N-pr.-gruppe.
SELECT
department,
name,
salary,
ROW_NUMBER() OVER (
PARTITION BY department
ORDER BY salary DESC
) AS dept_rn
FROM employees;ROW_NUMBER og ens værdier: Der er ingen delte placeringer
Vigtigt til jobsamtalen: Når to rækker har samme sorteringsværdi, giver ROW_NUMBER dem stadig forskellige numre. Hvilken række der får det laveste nummer, er ikke-deterministisk, medmindre du tilføjer en kolonne, der afgør rækkefølgen ved ens værdier.
RANKville give rækker med samme værdi samme rang.ROW_NUMBERvælger vilkårligt en rækkefølge blandt dem.
For at gøre resultaterne reproducerbare skal du altid tilføje en unik afgørende sorteringskolonne til ORDER BY.
SELECT
name,
salary,
ROW_NUMBER() OVER (
ORDER BY salary DESC, employee_id -- employee_id breaks ties deterministically
) AS rn
FROM employees;Reglen for entydig afgørelse ved ens værdier
Hvis din ORDER BY ikke definerer en entydig rækkefølge, fordi ingen kombination af kolonner er unik, kan rækkenummereringen ændre sig mellem kørsler, selv på de samme data. Interviewere indsætter ofte denne faldgrube i spørgsmål om sideinddeling og "seneste post".
Tommelfingerregel: Føj en primærnøgle eller en anden unik kolonne til som den sidste sorteringsnøgle, når resultatet skal være stabilt.
-- Unstable: many rows can share the same created_at
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)
-- Stable: id guarantees a single deterministic winner
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC, id DESC)Gennemgået eksempel: Seneste ordre pr. kunde
Et klassisk spørgsmål: "Returner hver kundes seneste ordre." Nummerér ordrer pr. kunde efter dato i faldende rækkefølge, og behold rn = 1 i en ydre forespørgsel.
Da ROW_NUMBER garanterer præcis én række med nummer 1 pr. partition, får du præcis én række pr. kunde — ingen dubletter, selv hvis to ordrer har samme tidsstempel, fordi den afgørende sorteringskolonne løser det.
SELECT customer_id, order_id, order_date, amount
FROM (
SELECT
customer_id, order_id, order_date, amount,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC, order_id DESC
) AS rn
FROM orders
) t
WHERE rn = 1;Fjernelse af dubletter i rækker
ROW_NUMBER er det enkleste værktøj til fjernelse af dubletter. Partitionér efter de kolonner, der definerer en dublet, sortér efter en præferenceregel, og behold rn = 1.
Her betragter vi rækker med samme e-mailadresse som dubletter og beholder den tidligst oprettede. Alt med rn > 1 er en dublet, som du kan slette eller ignorere.
SELECT id, email, created_at
FROM (
SELECT
id, email, created_at,
ROW_NUMBER() OVER (
PARTITION BY email
ORDER BY created_at ASC, id ASC
) AS rn
FROM users
) t
WHERE rn = 1;ROW_NUMBER til sideinddeling
Før OFFSET/FETCH blev universelt understøttet, blev sideinddeling udført med ROW_NUMBER, og det bruges stadig i SQL Server og mange ETL-job. Nummerér rækker i en stabil rækkefølge, og filtrér derefter et nummereret interval i en ydre forespørgsel.
Vær opmærksom på dette ved jobsamtaler: Sideinddeling er kun korrekt, hvis rækkefølgen er deterministisk — ellers kan den samme række optræde på to sider eller blive sprunget helt over.
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY created_at, id) AS rn
FROM articles
) t
WHERE rn BETWEEN 21 AND 40; -- page 2, 20 per pageTildeling af en sekvens til omordning af data
Nogle gange har du blot brug for et sekventielt indeks, f.eks. til at omnummerere rækker efter en sortering, oprette en etiket fra 1 til N eller parre rækker med en genereret serie. ROW_NUMBER over den ønskede rækkefølge giver en ren, tæt sekvens uden huller.
Det er også sådan, du giver et vilkårligt, uordnet sæt en stabil position til senere sammenføjning.
SELECT
ROW_NUMBER() OVER (ORDER BY score DESC, player_id) AS leaderboard_position,
player_id,
score
FROM scores;ROW_NUMBER kontra COUNT for den n. række
Når du bliver spurgt efter "den tredje seneste ordre" eller "den anden række", skal du vælge ROW_NUMBER og filtrere på den nøjagtige værdi i en ydre forespørgsel. Da nummereringen er unik, returnerer rn = 3 præcis én række.
Modsat RANK: Hvis du vil have den anden særskilte værdi, f.eks. den næsthøjeste løn, hvor ens værdier tæller én gang, er ROW_NUMBER det forkerte værktøj — det kræver DENSE_RANK, som gennemgås i næste lektion.
SELECT order_id, order_date
FROM (
SELECT order_id, order_date,
ROW_NUMBER() OVER (ORDER BY order_date DESC, order_id DESC) AS rn
FROM orders
) t
WHERE rn = 3; -- exactly the 3rd most recent orderOpsummering af faldgruber
Hold styr på disse ting, når du er under pres til en jobsamtale:
ROW_NUMBERer altid unik og uden huller inden for en partition.- Den kræver en
ORDER BYiOVER; uden en unik afgørende sorteringskolonne er resultaterne ikke-deterministiske ved ens værdier. - Den kan ikke filtreres i
WHERE— pak den ind i en underforespørgsel eller CTE. - Brug den til én række pr. gruppe, fjernelse af dubletter og sideinddeling; brug
DENSE_RANK, når rækker med samme værdi skal have samme nummer.
Hurtigt tjek
Hvordan håndterer ROW_NUMBER rækker med samme værdi i ORDER BY?
Opsummering: Deterministisk sekvensering
ROW_NUMBER er dit værktøj til unik nummerering uden huller inden for partitioner. Du har lært at:
- Nummerere hele sæt og grupper pr. partition.
- Tilføje en unik afgørende sorteringskolonne for deterministiske og reproducerbare resultater.
- Løse problemer med seneste række pr. nøgle, fjernelse af dubletter, sideinddeling og den n.-te række ved at filtrere
rni en ydre forespørgsel.
Dernæst ser du, hvordan RANK og DENSE_RANK bevidst giver rækker med samme værdi samme nummer — og hvordan deres håndtering af huller adskiller sig.
Lær Forberedelse til kodeinterviews med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 90
- Lektioner
- 360
Ofte stillede spørgsmål
Er lektionen “ROW_NUMBER til entydig sekvensering” gratis?
Ja — hele teksten til “ROW_NUMBER til entydig sekvensering” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Forberedelse til kodeinterviews-kurset, skal du opgradere til CoddyKit PRO. Forberedelse til kodeinterviews-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “ROW_NUMBER til entydig sekvensering”?
Tildel et deterministisk rækkenummer inden for hver partition Du øver dig i Forberedelse til kodeinterviews med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Forberedelse til kodeinterviews?
Der kræves ingen tidligere erfaring. Forberedelse til kodeinterviews på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “ROW_NUMBER til entydig sekvensering”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Forberedelse til kodeinterviews-lektion?
Ja. Alle Forberedelse til kodeinterviews-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- OVER, PARTITION BY og ORDER BY
- ROW_NUMBER til entydig sekvensering
- RANK kontra DENSE_RANK ved ligheder
- Filtrering på et vinduesresultat