You do not need to UNPIVOT
and then PIVOT
. You can use a CASE
statement and compare the columns values using GREATEST
, for the maximum, and LEAST
, for the minimum:
SELECT student_name,
CASE
WHEN maths = LEAST(maths, science, social) THEN 'Maths'
WHEN science = LEAST(maths, science, social) THEN 'Science'
WHEN social = LEAST(maths, science, social) THEN 'Social'
END AS minimum,
CASE
WHEN maths = GREATEST(maths, science, social) THEN 'Maths'
WHEN science = GREATEST(maths, science, social) THEN 'Science'
WHEN social = GREATEST(maths, science, social) THEN 'Social'
END AS maximum
FROM student;
Which, for the sample data:
CREATE TABLE student (Student_Name, Maths, Science, Social) AS
SELECT 'A', 20, 30, 10 FROM DUAL UNION ALL
SELECT 'B', 10, 20, 30 FROM DUAL UNION ALL
SELECT 'C', 10, 10, 10 FROM DUAL;
Outputs:
STUDENT_NAME |
MINIMUM |
MAXIMUM |
A |
Social |
Science |
B |
Maths |
Social |
C |
Maths |
Maths |
If you want to show all the subjects in the case of a tie for minimum or maximum then you can use:
SELECT student_name,
LTRIM(
CASE WHEN maths = LEAST(maths, science, social) THEN 'Maths' END
|| CASE WHEN science = LEAST(maths, science, social) THEN ', Science' END
|| CASE WHEN social = LEAST(maths, science, social) THEN ', Social' END,
', '
) AS minimum,
LTRIM(
CASE WHEN maths = GREATEST(maths, science, social) THEN 'Maths' END
|| CASE WHEN science = GREATEST(maths, science, social) THEN ', Science' END
|| CASE WHEN social = GREATEST(maths, science, social) THEN ', Social' END,
', '
) AS maximum
FROM student;
Which outputs:
STUDENT_NAME |
MINIMUM |
MAXIMUM |
A |
Social |
Science |
B |
Maths |
Social |
C |
Maths, Science, Social |
Maths, Science, Social |
db<>fiddle here