How to write a SQL query to find top n values in each row of a table?

1 minute read

Problem Description:

Let consider the following table that represents the grade of students for different courses:

ooo

The question is how the grades can be sorted in the descending order for each student. The desired output should be as follows:

ooo

Solution:

To sort records based on only one course, let say Physics, the following SQL query can be used in Postgres:

SELECT *
FROM
  grades
ORDER BY Physics  DESC

As a result, top grades for Physics course are sorted in the descending order.

To obtain the desired solution, first a temporary table should be created and then the grades will be sorted in the descending order. Since “for” loop cannot be used in SQL queries to find each of the grades and store them in different columns, similar queries with different offsets are used. Hence, the following query can be used:

SELECT *,

(SELECT Max(x)
        FROM (VALUES (Biology),(Physics),(Calculus)) AS Y(x) ) AS highest_grade
,
(SELECT x
        FROM (VALUES (Biology),(Physics),(Calculus)) AS Y(x) ORDER BY x DESC OFFSET 1 ROWS FETCH next 1 ROWS ONLY ) AS second_highest_grade,
(SELECT x
        FROM (VALUES (Biology),(Physics),(Calculus)) AS Y(x) ORDER BY x DESC OFFSET 2 ROWS FETCH next 1 ROWS ONLY ) AS third_highest_grade

FROM
(SELECT *
FROM grades) AS T

The source code of this project is available in my Github page.

Tags:

Updated: