Förberedelse inför kodningsintervjuer · Lektion

Högst avlönad per avdelning

Kombinera partitionering och rangordning för grupperade problem med de N högsta lönerna

Lektion 3 av 413 steg

Högst avlönad per avdelning är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 3 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.

Från global rangordning till rangordning per grupp

Nästa steg är frågan: "Hitta den högst betalda anställda på varje avdelning." Den kombinerar rangordning med gruppering och är en typisk fråga på mellannivå.

Anta en tabell employee med id, name, department_id och salary. Vi vill hitta en eller flera, vid lika löner, bäst betalda anställda per avdelning – inte bara det globala maximumet.

Det viktigaste nya verktyget är PARTITION BY, som startar om rangordningen inom varje avdelning.

CREATE TABLE employee (
  id            INT PRIMARY KEY,
  name          VARCHAR(100),
  department_id INT,
  salary        INT
);

PARTITION BY återställer rangordningen

När du lägger till PARTITION BY department_id i fönstret beräknar databasen rangordningen separat inom varje avdelning.

Varje avdelning börjar med sin egen rang 1. Den bäst betalda anställda på avdelning 1 och den bäst betalda anställda på avdelning 5 får alltså båda rang 1. Utan partitionering skulle bara det enda globala maximumet få rang 1.

SELECT name, department_id, salary,
       DENSE_RANK() OVER (
         PARTITION BY department_id
         ORDER BY salary DESC
       ) AS rnk
FROM employee;

Filtrering på rang 1

Om du bara vill behålla de bäst betalda anställda omsluter du den rangordnade frågan och filtrerar på rang 1. Som alltid måste fönsterfunktionen beräknas i en underfråga eller CTE innan du kan filtrera på den.

Om du använder DENSE_RANK eller RANK här innebär det att båda returneras om två anställda har samma högsta lön på en avdelning. Det är vanligtvis den korrekta tolkningen av "den bäst betalda anställda".

SELECT name, department_id, salary
FROM (
  SELECT name, department_id, salary,
         DENSE_RANK() OVER (
           PARTITION BY department_id
           ORDER BY salary DESC
         ) AS rnk
  FROM employee
) t
WHERE rnk = 1;

ROW_NUMBER när exakt en rad önskas

Ibland vill intervjuaren ha exakt en rad per avdelning även när lönen är lika. Använd då ROW_NUMBER och lägg till ett deterministiskt skiljekriterium, till exempel det lägsta värdet för id.

Utan skiljekriteriet avgörs lika resultat godtyckligt och resultatet blir icke-deterministiskt. Om , id ASC läggs till blir valet upprepningsbart.

SELECT name, department_id, salary
FROM (
  SELECT name, department_id, salary,
         ROW_NUMBER() OVER (
           PARTITION BY department_id
           ORDER BY salary DESC, id ASC
         ) AS rn
  FROM employee
) t
WHERE rn = 1;

DENSE_RANK kontra ROW_NUMBER kontra RANK i det här fallet

Välj utifrån den exakta formuleringen:

  • DENSE_RANK = 1: alla anställda som delar den högsta lönen i varje avdelning.
  • RANK = 1: identiskt med DENSE_RANK för den högsta rangen (luckor spelar bara roll under rang 1).
  • ROW_NUMBER = 1: exakt en anställd per avdelning, där lika resultat avgörs av er ORDER BY.

Det intervjuaren bedömer är om ni kan ange vilken ni valde och varför.

Den korrelerade metoden före fönsterfunktioner

Innan fönsterfunktioner fanns var standardlösningen en korrelerad underfråga: behåll en rad bara om ingen i samma avdelning har högre lön.

Detta returnerar naturligt alla lika högst avlönade. Metoden är portabel men kan vara långsam, eftersom den inre MAX-beräkningen görs för varje yttre rad om optimeraren inte skriver om frågan.

SELECT e.name, e.department_id, e.salary
FROM employee e
WHERE e.salary = (
  SELECT MAX(e2.salary)
  FROM employee e2
  WHERE e2.department_id = e.department_id
);

JOIN-metoden med GROUP BY

Ytterligare ett portabelt mönster är att beräkna den högsta lönen per avdelning med GROUP BY och sedan göra en join tillbaka för att hämta de matchande anställda.

Detta är effektivt och tydligt. Joinen tar med alla anställda vars lön är lika med den högsta lönen i deras avdelning, så lika resultat bevaras.

SELECT e.name, e.department_id, e.salary
FROM employee e
JOIN (
  SELECT department_id, MAX(salary) AS max_sal
  FROM employee
  GROUP BY department_id
) m
  ON e.department_id = m.department_id
 AND e.salary = m.max_sal;

De N högst avlönade per avdelning

Mönstret kan utökas till "de 3 högst avlönade per avdelning" utan några nya idéer. Ändra bara filtret till ett intervall.

Med DENSE_RANK returnerar rnk <= 3 de tre högsta distinkta lönenivåerna (eventuellt fler än tre rader vid lika lön). Med ROW_NUMBER returnerar rn <= 3 exakt tre rader per avdelning.

SELECT name, department_id, salary
FROM (
  SELECT name, department_id, salary,
         DENSE_RANK() OVER (
           PARTITION BY department_id
           ORDER BY salary DESC
         ) AS rnk
  FROM employee
) t
WHERE rnk <= 3;

Genomgång av exempel

Avdelning 1: Ana 120, Bob 120, Cara 90. Avdelning 2: Dan 200, Eve 150.

  • DENSE_RANK = 1: Ana (120) och Bob (120) från avdelning 1 samt Dan (200) från avdelning 2. Tre rader.
  • ROW_NUMBER = 1 med id som skiljekriterium: en av Ana och Bob (den som har lägst id) samt Dan. Två rader.

Samma data kan ge olika antal rader beroende på funktionen. Välj den som motsvarar frågan.

Inkludera avdelningar och hämta namn

Intervjuare lägger ofta till en department-tabell och frågar efter avdelningens namn. Gör bara joinen efter rangordningen.

Behåll rangordningen på employee-tabellen och anslut uppslagstabellen sist, så att partitioneringen fortfarande sker på rätt granularitetsnivå.

SELECT d.name AS department, t.name AS employee, t.salary
FROM (
  SELECT name, department_id, salary,
         DENSE_RANK() OVER (
           PARTITION BY department_id ORDER BY salary DESC
         ) AS rnk
  FROM employee
) t
JOIN department d ON d.id = t.department_id
WHERE t.rnk = 1;

Vanliga fallgropar

Vanliga misstag vid rangordning per grupp:

  • Att glömma PARTITION BY och rangordna globalt, vilket bara returnerar den högst avlönade i hela företaget.
  • Att använda ROW_NUMBER när frågan antyder att alla lika resultat ska visas, vilket i tysthet tar bort flera högst avlönade med samma lön.
  • Att försöka placera fönsterfunktionen direkt i WHERE i stället för att kapsla in den.
  • Att ansluta department-tabellen före rangordningen och av misstag ändra partitioneringens granularitet.

Snabbkontroll

Välj rätt rangordningsfunktion för kravet.

Sammanfattning

Mönstret för högst avlönad per avdelning är det globala rangordningsmönstret plus PARTITION BY department_id:

  • DENSE_RANK = 1 returnerar alla lika högst avlönade per avdelning.
  • ROW_NUMBER = 1 med ett skiljekriterium returnerar exakt en per avdelning.
  • Portabla alternativ är en korrelerad MAX per avdelning eller den högsta GROUP BY-lönen som ansluts tillbaka till tabellen.

Utöka till de N högsta genom att ändra = 1 till <= N. Säg högt hur lika resultat ska hanteras.

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 ”Högst avlönad per avdelning” gratis?

Ja – hela texten till ”Högst avlönad per avdelning” 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 ”Högst avlönad per avdelning”?

Kombinera partitionering och rangordning för grupperade problem med de N högsta lönerna 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 3 av 4.

Hur lång tid tar lektionen ”Högst avlönad per avdelning”?

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. 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örberedelse inför kodningsintervjuer