Förberedelser inför SQL-intervjun · Lektion

Det n:te högsta värdet med DENSE_RANK

Generalisera till det n:te distinkta värdet och hantera dubbletter

Lektion 2 av 413 steg

Det n:te högsta värdet med DENSE_RANK är en gratis lektion i Förberedelser inför SQL-intervjun 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örberedelser inför SQL-intervjun, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelser inför SQL-intervjun innehåller totalt 4 lektioner.

Generalisering till den N:e högsta

När du väl kan hitta den näst högsta lönen kommer intervjuare direkt med nästa fråga: "Ge mig nu den N:e högsta." Det renaste och mest försvarbara svaret använder DENSE_RANK.

Mönstret är alltid detsamma: rangordna unika löner i fallande ordning och filtrera sedan fram raden vars rang är lika med N. Eftersom logiken inte förändras när N ändras besvarar den här metoden en hel familj av frågor.

Vi bygger upp lösningen, hanterar lika löner och dubbletter och diskuterar varför DENSE_RANK är rätt rangordningsfunktion för semantik med "unika värden".

Grundmallen

Här är den återanvändbara mallen för den N:e högsta lönen. Ersätt konstanten med det N som intervjuaren frågar efter.

Du beräknar DENSE_RANK i en inre fråga, eftersom fönsterfunktionen inte kan användas i WHERE, och filtrerar sedan på rnk = N utanför. För den tredje högsta lönen anger du rnk = 3 i filtret.

SELECT salary AS nth_highest
FROM (
  SELECT salary,
         DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
  FROM employee
) ranked
WHERE rnk = 3;

Hur DENSE_RANK numrerar unika värden

DENSE_RANK tilldelar lika värden samma rang och lämnar aldrig någon lucka efteråt. Det är exakt den definition av "det N:e unika värdet" som intervjuare menar.

För lönerna 800, 800, 600, 600, 400:

  • 800 -> rang 1
  • 600 -> rang 2
  • 400 -> rang 3

Den tredje högsta lönen är alltså 400, trots att det finns fem rader. Dubbletter slås automatiskt ihop till en enda rang.

Varför RANK ger fel svar

Byt ut funktionen mot RANK, så blir svaret fel. RANK lämnar luckor som motsvarar antalet lika värden.

För 800, 800, 600, 600, 400:

  • 800, 800 -> rang 1 (två stycken)
  • 600, 600 -> rang 3 (en lucka, ingen rang 2)
  • 400 -> rang 5

Filtrering på rnk = 3 returnerar 600, medan rnk = 2 inte returnerar något. Om intervjuaren inte uttryckligen vill ha tävlingsrangordning är DENSE_RANK rätt för "den N:e unika lönen".

Varför ROW_NUMBER också blir fel här

ROW_NUMBER tilldelar varje rad ett unikt nummer och ignorerar helt lika värden. För 800, 800, 600, 600, 400 blir resultatet 1, 2, 3, 4, 5.

rn = 3 returnerar alltså 600, men rn = 2 returnerar dubbletten 800, inte det näst högsta unika värdet. ROW_NUMBER besvarar frågan "den N:e raden", inte "det N:e unika värdet".

Använd ROW_NUMBER bara när frågan verkligen gäller en specifik rad, till exempel vid deduplicering eller top-N per grupp när exakt en rad ska behållas.

SELECT salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
FROM employee;

Säker parametrisering av N

I riktig kod skulle du inte hårdkoda rangen. Skicka in N som en parameter och jämför med den. Fönsterdefinitionen förblir identisk; bara det yttre filtret parameteriseras.

Här kan du också returnera alla löner som delar rang N: eftersom DENSE_RANK ger lika värden samma rang kan WHERE rnk = N returnera flera rader om flera anställda har den N:e unika lönen, vilket ofta är det önskade beteendet.

SELECT id, salary
FROM (
  SELECT id, salary,
         DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
  FROM employee
) ranked
WHERE rnk = :n;

Generalisering med korrelerad räkning

Metoden från tiden före fönsterfunktioner generaliseras också: en lön är den N:e högsta unika lönen när exakt N - 1 unika löner är strikt högre än den.

För den tredje högsta lönen krävs exakt två unika högre löner. Detta fungerar i äldre databasmotorer utan fönsterfunktioner, men skalar dåligt eftersom den inre räkningen körs om för varje yttre rad.

SELECT DISTINCT salary AS nth_highest
FROM employee e
WHERE (
  SELECT COUNT(DISTINCT e2.salary)
  FROM employee e2
  WHERE e2.salary > e.salary
) = 2;

MySQLs funktionsform som intervjuare brukar fråga efter

Problemet "Nth highest salary" i LeetCode-stil ber ofta om en lagrad funktion som returnerar ett enda värde. Funktionskroppen är bara DENSE_RANK-mallen, omsluten så att den returnerar en lön.

Du behöver inte memorera exakt funktionssyntax inför en intervju, men det är värt att känna igen att LIMIT N-1, 1 över unika löner är det kompakta MySQL-idiomet.

SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
LIMIT 1 OFFSET 2;  -- N = 3, so OFFSET N-1

Genomarbetat exempel: den 4:e högsta

Löner: 1000, 900, 900, 700, 500, 500, 300.

Unika värden i fallande ordning med DENSE_RANK:

  • 1000 -> 1
  • 900 -> 2
  • 700 -> 3
  • 500 -> 4
  • 300 -> 5

Den 4:e högsta lönen är 500. Observera att båda raderna med 500 har rang 4, så om du även väljer deras id:n returnerar filtrering på rnk = 4 båda anställda som tjänar 500.

Prestanda

Hur står sig metoderna i stor skala?

  • DENSE_RANK: en sortering av data följd av ett filter. Effektivt, och frågeplaneraren kan använda ett index på salary för sorteringen.
  • Korrelerad räkning: potentiellt O(n²), eftersom det inre aggregatet körs för varje rad. Undvik detta i stora tabeller.
  • LIMIT/OFFSET: snabbt för små N, men måste fortfarande sortera, och stora offsetvärden skannar och kasserar många rader.

Börja med DENSE_RANK så blir det sällan fel.

Specialfall att nämna

Starka kandidater tar upp specialfallen innan de blir tillfrågade:

  • N är större än antalet unika löner: filtret matchar inga rader och resultatet blir tomt. I lektion 4 går vi igenom hur man tvingar fram ett enda NULL.
  • Lika löner på rang N: DENSE_RANK returnerar alla anställda med samma lön. Avgör om det är det du vill ha.
  • N = 1: mallen fungerar fortfarande och returnerar maximum.

Snabbtest

Tillämpa mallen för den N:e högsta.

Sammanfattning

Den N:e högsta lönen har ett självklart standardsvar: rangordna unika löner med DENSE_RANK() OVER (ORDER BY salary DESC) i en underfråga och filtrera sedan med WHERE rnk = N.

  • DENSE_RANK betyder "det N:e unika värdet", där lika värden delar rang och inga luckor uppstår.
  • RANK skapar luckor och ROW_NUMBER räknar rader i stället för värden.
  • Tricket med korrelerad räkning = N-1 generaliserar samma idé utan fönsterfunktioner, men skalar dåligt.

Påpeka alltid specialfallet att "N överskrider antalet tillgängliga värden". Det löser vi härnäst.

Gratis att börja

Lär dig SQL 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
30
Lektioner
120

Vanliga frågor

Är lektionen ”Det n:te högsta värdet med DENSE_RANK” gratis?

Ja – hela texten till ”Det n:te högsta värdet med DENSE_RANK” 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örberedelser inför SQL-intervjun, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelser inför SQL-intervjun innehåller totalt 4 lektioner.

Vad lär jag mig i ”Det n:te högsta värdet med DENSE_RANK”?

Generalisera till det n:te distinkta värdet och hantera dubbletter Ni övar på Förberedelser inför SQL-intervjun 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örberedelser inför SQL-intervjun?

Du behöver inga förkunskaper. Utbildningen i Förberedelser inför SQL-intervjun 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 ”Det n:te högsta värdet med DENSE_RANK”?

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örberedelser inför SQL-intervjun-lektionen?

Ja. Varje Förberedelser inför SQL-intervjun-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. Näst högsta lönen på fem sätt
  2. Det n:te högsta värdet med DENSE_RANK
  3. Högst avlönad per avdelning
  4. Returnera NULL när inget n:te värde finns
← Tillbaka till Förberedelser inför SQL-intervjun