oracle-database

How can I display the average for every column at the bottom of the query?


I have 3 items - GAO, GAD and GAM and for every item I need to count average in the bottom of table, below "ALL".
Query:

SELECT NVL(vrz.DATA, 'ALL') AS DAY,
SUM(vrz.SOV_GAO_1_ILE) AS GAO,
SUM(vrz.SOV_GAD_2_ILE) AS GAD,
SUM(vrz.SOV_GAM_3_ILE) AS GAM,
SUM(vrz.SOV_GAO_1_ILE) + SUM(vrz.SOV_GAD_2_ILE) + SUM(vrz.SOV_GAM_3_ILE) AS SUMMARY,
FLOOR((SUM(vrz.SOV_GAO_1_ILE) + SUM(vrz.SOV_GAD_2_ILE) + 
SUM(vrz.SOV_GAM_3_ILE))/3) AS AVERAGE
FROM PLC.V_RAPORT_ZDARZEN vrz
GROUP BY ROLLUP (vrz.DATA)

Part of data:

DAY         GAO     GAD     GAM   SUMMARY   AVERAGE
2017-05-25  1035,0  725,0   0,0   1760,0    586,0
2017-05-26  253,0   785,0   0,0 1038,0  346,0
2017-05-29  1060,0  467,0   0,0 1527,0  509,0
2017-05-30  922,0   905,0   0,0 1827,0  609,0
2017-05-31  1113,0  1343,0  0,0 2456,0  818,0
2017-06-01  1236,0  1057,0  0,0 2293,0  764,0
2017-06-02  1740,0  1182,0  0,0 2922,0  974,0
2017-06-04  22,0    1,0 0,0 23,0    7,0
2017-06-05  1702,0  1534,0  0,0 3236,0  1078,0
2017-06-06  1754,0  1388,0  0,0 3142,0  1047,0
2017-06-07  865,0   1109,0  0,0 1974,0  658,0
2017-06-08  1248,0  1044,0  0,0 2292,0  764,0
2017-06-09  752,0   978,0   0,0 1730,0  576,0
2017-06-12  1403,0  534,0   0,0 1937,0  645,0
2017-06-13  2415,0  850,0   0,0 3265,0  1088,0
2017-06-14  1159,0  458,0   0,0 1617,0  539,0
2017-06-16  361,0   372,0   0,0 733,0   244,0
2017-06-19  1605,0  393,0   0,0 1998,0  666,0
2017-06-20  938,0   694,0   0,0 1632,0  544,0
2017-06-21  2212,0  952,0   0,0 3164,0  1054,0
2017-06-22  1912,0  922,0   0,0 2834,0  944,0
2017-06-23  1030,0  1003,0  0,0 2033,0  677,0
2017-06-26  528,0   111,0   0,0 639,0   213,0
2017-06-27  910,0   485,0   0,0 1395,0  465,0
2017-06-28  708,0   240,0   0,0 948,0   316,0
2017-06-29  1819,0  1122,0  0,0 2941,0  980,0
.......
2017-11-03  809,0   585,0   600,0   1994,0  664,0
2017-11-06  953,0   1474,0  595,0   3022,0  1007,0
2017-11-07  800,0   1250,0  991,0   3041,0  1013,0
2017-11-08  0,0     615,0   1014,0  1629,0  543,0
ALL         131029,0    124262,0    112195,0    367486,0    122495,0

Averages: GAO GAD GAM 1082,884298 1027,834711 927,231405

Picture that illustrates my data


Solution

  • Rollup is OK, but in this case I would use CTE and add two summary rows using union all.

    with cte as (
        select data, count(1) cnt,
               sum(sov_gao_1_ile) gao, sum(sov_gad_2_ile) gad, sum(sov_gam_3_ile) gam,
               sum(sov_gao_1_ile + sov_gad_2_ile + sov_gam_3_ile) / 3 average
          from vrz
          group by data)
    select to_char(data, 'yyyy-mm-dd') data, gao, gad, gam, gao+gad+gam summary, average 
      from cte
    union all 
    select 'ALL', sum(gao), sum(gad), sum(gam), sum(gao+gad+gam), sum(average)
      from cte
    union all
    select 'AVG', round(avg(gao)), round(avg(gad)), round(avg(gam)), null, null
      from cte
      order by 1
    

    As I understand, You want averages from already grouped data, which can differ from average from the whole set. If not then @Wernfried's solution should work for You. Anyway you can use column cnt to divide sums by counts.

    Unions works on aggregated sums, so it should not impact performance. Simplified demo data and output:

    with vrz(data, sov_gao_1_ile, sov_gad_2_ile, sov_gam_3_ile) as (
        select date '2000-01-21', 111, 112, 114 from dual union all
        select date '2000-01-21', 115, 116, 125 from dual union all
        select date '2000-01-22', 211, 212, 213 from dual union all
        select date '2000-01-22', 215, 216, 223 from dual union all
        select date '2000-01-23', 301, 302, 225 from dual),
    cte as (
        select data, count(1) cnt,
               sum(sov_gao_1_ile) gao, sum(sov_gad_2_ile) gad, sum(sov_gam_3_ile) gam,
               sum(sov_gao_1_ile + sov_gad_2_ile + sov_gam_3_ile) / 3 average
          from vrz
          group by data)
    select to_char(data, 'yyyy-mm-dd') data, gao, gad, gam, gao+gad+gam summary, average 
      from cte
    union all 
    select 'ALL', sum(gao), sum(gad), sum(gam), sum(gao+gad+gam), sum(average) 
      from cte
    union all
    select 'AVG', round(avg(gao)), round(avg(gad)), round(avg(gam)), null, null 
      from cte
      order by 1
    
    
    
    DATA              GAO        GAD        GAM    SUMMARY    AVERAGE
    ---------- ---------- ---------- ---------- ---------- ----------
    2000-01-21        226        228        239        693        231
    2000-01-22        426        428        436       1290        430
    2000-01-23        301        302        225        828        276
    ALL               953        958        900       2811        937
    AVG               318        319        300