SQL查询:按行逐列的所有行的AVG和MEAN

时间:2019-03-06 09:40:14

标签: sql oracle

我有一个包含10个标记列的表格,如下所示:

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

我需要编写查询以以下格式返回每个标记的AVG,平均值,媒体

SUB     MEAN    AVG   MEDIAN    STD   MIN   MAX
MARK1                       
MARK2                       
MARK3   

以下查询将按列的方式返回每个传递的列,但是我需要按行的方式显示每个列(MARKS),并伴随列中的聚合/计算。

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

4 个答案:

答案 0 :(得分:2)

在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 

Online Demo

答案 1 :(得分:1)

您可以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 |
+-------------+------+--------+-------------------------------------------+-----+-----+

您完成了。

答案 2 :(得分:0)

您可以获得每个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

答案 3 :(得分:0)

我将先取消数据透视,然后进行一次汇总。

以下内容适用于所有版本的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。