Förberedelse inför kodningsintervjuer · Lektion

ROW_NUMBER för unik numrering

Tilldela ett deterministiskt radnummer inom varje partition

Lektion 2 av 413 steg

ROW_NUMBER för unik numrering är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Förberedelse inför kodningsintervjuer, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.

Vad ROW_NUMBER garanterar

ROW_NUMBER() tilldelar varje rad inom sin partition ett unikt heltal utan luckor, med början på 1 och enligt fönstrets ORDER BY. Inga två rader får någonsin samma nummer, inte ens när deras sorteringsvärden är identiska.

Det är just denna unikhet som gör att intervjuare använder funktionen för att lösa problem med att "välja en rad per grupp" och deduplicering. De andra rankningsfunktionerna (RANK, DENSE_RANK) garanterar inte unikhet vid lika värden.

Minimal ROW_NUMBER-fråga

Den enklaste formen numrerar en hel resultatmängd i en vald ordning. ROW_NUMBER behöver alltid en ORDER BY inuti OVER — utan den skulle numreringen bli godtycklig, och de flesta databasmotorer avvisar eller varnar för den.

Här blir den senast anställda personen rad 1 om ni sorterar efter anställningsdatum i fallande ordning.

SELECT
  name,
  hire_date,
  ROW_NUMBER() OVER (ORDER BY hire_date DESC) AS rn
FROM employees;

Numrering inom partitioner

Lägg till PARTITION BY för att numrera raderna oberoende av varandra inom varje grupp. Räknaren återställs till 1 vid varje nytt partitionsvärde.

I exemplet får varje avdelning sin egen sekvens 1, 2, 3, sorterad efter lön. Den högst avlönade personen i varje avdelning får nummer 1 — grunden till mönstret top-N-per-group.

SELECT
  department,
  name,
  salary,
  ROW_NUMBER() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS dept_rn
FROM employees;

ROW_NUMBER och lika värden: inga delade placeringar

En viktig poäng i intervjuer: när två rader har samma sorteringsvärden ger ROW_NUMBER dem ändå olika nummer. Vilken som får det lägre numret är inte deterministiskt om ni inte lägger till en skiljekolumn.

  • RANK skulle ge rader med lika värden samma rang.
  • ROW_NUMBER väljer godtyckligt en ordning mellan dem.

Lägg alltid till en unik skiljekolumn i ORDER BY för att få reproducerbara resultat.

SELECT
  name,
  salary,
  ROW_NUMBER() OVER (
    ORDER BY salary DESC, employee_id  -- employee_id breaks ties deterministically
  ) AS rn
FROM employees;

Regeln om en deterministisk skiljekolumn

Om er ORDER BY inte anger en strikt ordning (ingen kombination av kolumner är unik) kan radnumreringen ändras mellan körningar, även för samma data. Intervjuare lägger in denna fallgrop i frågor om paginering och "senaste posten".

Tumregel: lägg till en primärnyckel eller annan unik kolumn som sista sorteringsnyckel när resultatet måste vara 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)

Genomräknat exempel: Senaste ordern per kund

En standardfråga: "Returnera varje kunds senaste order." Numrera order per kund efter datum i fallande ordning och behåll sedan rn = 1 i en yttre fråga.

Eftersom ROW_NUMBER garanterar exakt en rad med nummer 1 per partition får ni exakt en rad per kund — inga dubbletter, även om två order har samma tidsstämpel (skiljekolumnen avgör).

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;

Deduplicera rader

ROW_NUMBER är det renaste verktyget för deduplicering. Partitionera efter kolumnerna som definierar en dubblett, sortera enligt en preferensregel och behåll sedan rn = 1.

Här behandlar vi rader med samma e-postadress som dubbletter och behåller den som skapades först. Allt med rn > 1 är en dubblett som ni kan radera eller ignorera.

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 för paginering

Innan OFFSET/FETCH blev allmänt tillgängliga användes ROW_NUMBER för paginering, och det gör den fortfarande i SQL Server och många ETL-jobb. Numrera raderna i en stabil ordning och filtrera sedan ett numrerat intervall i en yttre fråga.

Observera i intervjuer att paginering bara är korrekt om ordningen är deterministisk — annars kan samma rad förekomma på två sidor eller hoppas över helt.

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 page

Tilldela en sekvens för att ordna om data

Ibland behövs bara ett sekventiellt index, till exempel för att numrera om rader efter en sortering, skapa en etikett från 1 till N eller para ihop rader med en genererad serie. ROW_NUMBER över den önskade ordningen ger en ren, tät sekvens utan luckor.

Detta är också sättet att ge en godtyckligt ordnad mängd en stabil position för en senare join.

SELECT
  ROW_NUMBER() OVER (ORDER BY score DESC, player_id) AS leaderboard_position,
  player_id,
  score
FROM scores;

ROW_NUMBER jämfört med COUNT för ”N:te raden”

När ni får frågan om "den tredje senaste ordern" eller "den andra raden" ska ni använda ROW_NUMBER och filtrera på det exakta värdet i en yttre fråga. Eftersom numreringen är unik returnerar rn = 3 exakt en rad.

Jämför med RANK: om ni vill ha det andra distinkta värdet (till exempel den näst högsta lönen där lika värden ska räknas en gång) är ROW_NUMBER fel verktyg — då behövs DENSE_RANK, som behandlas i nästa 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 order

Sammanfattning av fallgropar

Håll isär följande även under intervjupress:

  • ROW_NUMBER ger alltid unika nummer utan luckor inom en partition.
  • Det behöver en ORDER BY i OVER; utan en unik skiljekolumn blir resultaten inte deterministiska vid lika värden.
  • Det kan inte filtreras i WHERE — omslut det i en underfråga eller CTE.
  • Använd det för en rad per grupp, deduplicering och paginering; använd DENSE_RANK när lika värden måste dela nummer.

Snabbtest

Hur hanterar ROW_NUMBER rader som har samma värde för ORDER BY?

Repetition: Deterministisk sekvensering

ROW_NUMBER är verktyget för unik numrering utan luckor inom partitioner. Ni har lärt er att:

  • Numrera hela mängder och grupper per partition.
  • Lägga till en unik skiljekolumn för deterministiska och reproducerbara resultat.
  • Lösa problem med senaste raden per nyckel, deduplicering, paginering och N:te raden genom att filtrera rn i en yttre fråga.

Härnäst ser ni hur RANK och DENSE_RANK avsiktligt ger lika värden samma nummer — och hur deras beteende vad gäller luckor skiljer sig åt.

Gratis att börja

Lär dig Förberedelse inför kodningsintervjuer med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
90
Lektioner
360

Vanliga frågor

Är lektionen ”ROW_NUMBER för unik numrering” gratis?

Ja – hela texten till ”ROW_NUMBER för unik numrering” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Förberedelse inför kodningsintervjuer, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.

Vad lär jag mig i ”ROW_NUMBER för unik numrering”?

Tilldela ett deterministiskt radnummer inom varje partition Ni övar på Förberedelse inför kodningsintervjuer med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Förberedelse inför kodningsintervjuer?

Du behöver inga förkunskaper. Utbildningen i Förberedelse inför kodningsintervjuer på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”ROW_NUMBER för unik numrering”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Förberedelse inför kodningsintervjuer-lektionen?

Ja. Varje Förberedelse inför kodningsintervjuer-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. OVER, PARTITION BY och ORDER BY
  2. ROW_NUMBER för unik numrering
  3. RANK kontra DENSE_RANK vid lika värden
  4. Filtrera på ett fönsterresultat
← Tillbaka till Förberedelse inför kodningsintervjuer