Вы можете UNPIVOT
свои данные в отдельных строках и затем агрегировать.
Если вы просто UNPIVOT
, вы получите это:
WITH test_data ( S_ID, S_Name, MARK1, MARK2, MARK3) AS (
SELECT 1, 'TEST', 50, 60, 70 FROM DUAL UNION ALL
SELECT 2,' TEST_!', 40, 50, 40 FROM DUAL )
SELECT *
FROM test_data
UNPIVOT ( mark_value FOR mark_number IN ( MARK1, MARK2, MARK3 ) )
+------+---------+-------------+------------+
| S_ID | S_NAME | MARK_NUMBER | MARK_VALUE |
+------+---------+-------------+------------+
| 1 | TEST | MARK1 | 50 |
| 1 | TEST | MARK2 | 60 |
| 1 | TEST | MARK3 | 70 |
| 2 | TEST_! | MARK1 | 40 |
| 2 | TEST_! | MARK2 | 50 |
| 2 | TEST_! | MARK3 | 40 |
+------+---------+-------------+------------+
Оттуда вам просто нужно GROUP BY
и вычислить ваши агрегаты, так что это будет последний запрос, который вам понадобится:
SELECT mark_number,
avg(mark_value) as mean,
median(mark_value) as median,
stddev(mark_value) as std,
min(mark_value) as min,
max(mark_value) as max
FROM test_data
UNPIVOT ( mark_value FOR mark_number IN ( MARK1, MARK2, MARK3 ) )
group by mark_number
+-------------+------+--------+-------------------------------------------+-----+-----+
| MARK_NUMBER | MEAN | MEDIAN | STD | MIN | MAX |
+-------------+------+--------+-------------------------------------------+-----+-----+
| MARK1 | 45 | 45 | 7.07106781186547524400844362104849039285 | 40 | 50 |
| MARK2 | 55 | 55 | 7.07106781186547524400844362104849039285 | 50 | 60 |
| MARK3 | 55 | 55 | 21.21320343559642573202533086314547117854 | 40 | 70 |
+-------------+------+--------+-------------------------------------------+-----+-----+
И вы 'готово.