Knowledge Guide
HomeDatabasesSQL Practice Problems

hard School Top Achievers by Subject

DENSE_RANK() hands every row a rank by walking the ordered scores within each partition and incrementing the rank only when the score value changes — so equal scores collapse onto the same rank and no rank numbers are skipped. That single property is the whole problem: "top three unique scores" is the definition of "DENSE_RANK <= 3", and getting it right depends entirely on which of the three ranking functions you reach for.

Problem

Two tables. Student(id, name, score, subjectId) records one student's score in one subject; Subject(id, name) names each subject. Return, per subject, every student whose score is among the top three distinct scores for that subject. Ties on a qualifying score all stay in — so a subject can return more than three rows.

The query

Rank inside each subject, then keep ranks 1–3. The ranking has to happen in a subquery (or CTE) because a window function cannot appear in a WHERE clause — WHERE is evaluated before the window functions are computed.

SELECT su.name  AS Subject,
       st.name  AS Student,
       st.score AS Score
FROM (
    SELECT subjectId,
           name,
           score,
           DENSE_RANK() OVER (
               PARTITION BY subjectId
               ORDER BY score DESC
           ) AS s_rank
    FROM Student
) st
JOIN Subject su ON st.subjectId = su.id
WHERE st.s_rank <= 3
ORDER BY su.name, st.score DESC;

PARTITION BY subjectId restarts the ranking for each subject; ORDER BY score DESC makes rank 1 the highest score; the outer WHERE s_rank <= 3 keeps the top three distinct score tiers.

Worked trace on the real data

Math (subjectId 1) holds Alice 92, Derek 95, Elisa 88, Fiona 92, George 90. Walk them in score DESC order and assign DENSE_RANK, bumping the rank only when the score drops to a new value:

score (DESC)studentnew value?DENSE_RANKkept (≤3)?
95Derekyes → 11yes
92Aliceyes → 22yes
92Fionasame as Alice2yes
90Georgeyes → 33yes
88Elisayes → 44no — dropped

The 92 tie shares rank 2 and does not consume rank 3, so George at 90 still qualifies and Elisa at 88 lands at rank 4 and is cut. Science (subjectId 2) has only Carol 87 (rank 1) and Bob 85 (rank 2); both fit inside three. Final result: Math → Derek 95, Alice 92, Fiona 92, George 90; Science → Carol 87, Bob 85.

diagram
diagram

Why the obvious alternatives are wrong

The diagram shows the divergence on the 92/92/90 stretch. Each function counts differently:

Pitfalls

Takeaways


Re-authored and deepened for this guide. Based on LeetCode's "Department Top Three Salaries" / "Nth Highest Salary" problem family and the SQL window-function specification (ISO/IEC 9075, OVER / PARTITION BY / ORDER BY). Ranking-function semantics cross-checked against the PostgreSQL documentation (Window Functions) and MySQL 8.0 reference (Window Function Descriptions). The grader-noted trace — Math ties at 92 sharing rank 2, George at 90 surviving as rank 3, Elisa at 88 dropped at rank 4 — was verified by hand against the supplied data, and the RANK / ROW_NUMBER / DENSE_RANK contrast that the original page asserted in one line is now demonstrated explicitly.

🤖 Don't fully get this? Learn it with Claude

Stuck on School Top Achievers by Subject? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **School Top Achievers by Subject** (Databases). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **School Top Achievers by Subject** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **School Top Achievers by Subject**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **School Top Achievers by Subject**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes