[英]How to transpose columns to rows and get the max and min value in Oracle
Input输入
Student_Name学生姓名 | Maths数学 | Science科学 | Social社会的 |
---|---|---|---|
A一种 | 20 20 | 30 30 | 10 10 |
B乙 | 10 10 | 20 20 | 30 30 |
Output Output
Student_Name学生姓名 | max_sub最大子 | min_sub最小子 |
---|---|---|
A一种 | Science科学 | Social社会的 |
B乙 | Social社会的 | 20Maths 20数学 |
I tried我试过了
select student_name,max(marks) m1, min(marks) m2
from
(
select student_name, engg, fre, sp from student)
unpivot (marks for subject in(engg, fre, sp)
)
group by student_name;
but no luck但没有运气
Unpivot, then re-pivot (or, simpler, just aggregate explicitly, as I show below):取消透视,然后重新透视(或者,更简单,只是显式聚合,如下所示):
with
student(student_name, math, science, social) as (
select 'A', 20, 30, 10 from dual union all
select 'B', 10, 20, 30 from dual
)
select student_name,
max(sub) keep (dense_rank last order by mark nulls first) as max_sub,
min(sub) keep (dense_rank first order by mark nulls last ) as min_sub
from student
unpivot (mark for sub in (math as 'Math', science as 'Science',
social as 'Social'))
group by student_name
;
STUDENT_NAME MAX_SUB MIN_SUB
------------ ------- -------
A Science Social
B Social Math
A few things are missing or plain wrong in your problem specification.您的问题说明中有一些缺失或明显错误。 First and most important, I do hope that in real life you have a student id column - different students may have the same name.首先也是最重要的,我希望在现实生活中你有一个学生 ID 列——不同的学生可能有相同的名字。 (One can work around that for this specific problem, but not in general.) (可以解决这个特定问题,但不是一般情况。)
Then - you need to specify how null
grades should be treated (what if a student simply doesn't have a grade in Math, for example), and what to show in the case of ties (a student has the same, highest grade in two different subjects).然后 - 您需要指定应如何处理null
成绩(例如,如果学生根本没有数学成绩怎么办),以及在平局的情况下要显示什么(学生在数学方面具有相同的最高成绩)两个不同的科目)。 I made one particular set of choices above - they may or may not be right for your use case.我在上面做了一组特定的选择——它们可能适合也可能不适合您的用例。 Any other choices can be accommodated easily, as soon as you say what they are.任何其他选择都可以很容易地适应,只要你说出它们是什么。
You do not need to UNPIVOT
and then PIVOT
.您不需要UNPIVOT
然后PIVOT
。 You can use a CASE
statement and compare the columns values using GREATEST
, for the maximum, and LEAST
, for the minimum:您可以使用CASE
语句并使用GREATEST
比较列值(最大值)和LEAST
(最小值):
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 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 C Maths, Science, Social数学、科学、社会 Maths, Science, Social数学、科学、社会
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.