SQL-запрос: AVG & MEAN для всех строк столбцов по строкам - PullRequest
0 голосов
/ 06 марта 2019

У меня есть таблица с 10 столбцами отметок, как показано ниже:

 S_ID   S_Name  MARK1   MARK2   MARK3
   1    TEST    50        60    70
   2    TEST_!  40        50    40

Мне нужно написать запрос для возврата AVG, MEAN, MEDIA для каждой отметки в формате ниже

SUB     MEAN    AVG   MEDIAN    STD   MIN   MAX
MARK1                       
MARK2                       
MARK3   

ниже запроса возвращать каждый переданный столбец в столбце, но мне нужен каждый столбец (MARKS) в строке, сопровождаемый агрегацией / вычислением в столбце.

select min(mark1), max(mark1) from  student;

Ответы [ 4 ]

2 голосов
/ 06 марта 2019

В MS SQL его можно получить, отключив.

DECLARE @table TABLE 
  ( 
     s_id   INT, 
     s_name VARCHAR(50), 
     mark1  INT, 
     mark2  INT, 
     mark3  INT 
  )

INSERT INTO @table
    VALUES (1, 'TEST', 50, 60, 70),
    (2, 'TEST_1', 40, 50, 40),
    (3, 'TEST_3', 20, 70, 80)

SELECT
    dtls
   ,SUM(sname) AS [SUM]
   ,AVG(sname) AS [AVG]
   ,STDEV(sname) AS [STD]
   ,MIN(sname) AS [MIN]
   ,MAX(sname) AS [MAX]
FROM @table
UNPIVOT (sname
FOR dtls IN (mark1,
mark2,
mark3)) AS unp
GROUP BY dtls 

Демонстрация в Интернете

1 голос
/ 07 марта 2019

Вы можете 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 |
+-------------+------+--------+-------------------------------------------+-----+-----+

И вы 'готово.

0 голосов
/ 06 марта 2019

Я бы сделал это, отключив данные, а затем выполнив одну агрегацию.

Следующее работает во всех версиях Oracle:

select sub,
       avg(mark1) as mean, median(mark1) as median,
       min(mark1) as min, max(mark1) as max
from ((select 'mark1' as sub, mark1 as mark from student
      ) union all
      (select 'mark2' as sub, mark1 as mark from student
      ) union all
      (select 'mark3' as sub, mark1 as mark from student
      )
     ) m
group by sub;

В Oracle 12C + я бы использовал боковое соединение для разворота данных.

Это облегчает добавление новой статистики - скажем, количества отметок, превышающих 90 - для всех трех столбцов.

0 голосов
/ 06 марта 2019

Вы можете получить все агрегированные столбцы для каждого SUB, а также столбец, имеющий статическое значение с указанием SUB, и объединить их все.

    SELECT 'MARK1' as SUB,AVG(mark1) as MEAN,MEDIAN(mark1) as MEDIAN,  min(mark1) as MIN, max(mark1) as MAX from student
    UNION
    SELECT 'MARK2' as SUB,AVG(mark2) as MEAN, MEDIAN(mark2) as MEDIAN,  min(mark2) as MIN, max(mark2) as MAX from student
    UNION
    SELECT 'MARK3' as SUB,AVG(mark3) as MEAN, MEDIAN(mark3) as MEDIAN,  min(mark3) as MIN, max(mark3) as MAX from student
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...