SQL计数月平均值和年初至今平均值

时间:2019-01-04 02:29:50

标签: sql oracle average

我想查询“月平均值”并与年初至今平均值相结合,我已经做过“月平均值”,但是没有结合年初至今平均值的线索。

sqlfiddle,由Avi Code先生编辑

sqlFiddle link

SELECT TO_CHAR(order_month, 'MON-YY'), order_avg
  FROM (
    SELECT TRUNC("Dayofmonth", 'MM') AS order_month, AVG("Numbervalue") AS order_avg
      FROM RAW_AVG
     GROUP BY TRUNC("Dayofmonth", 'MM')
     ORDER BY order_month
)

预期结果

| JAN-18 | 12.000000 |平均(1月)

| 2月18日| 13.423729 |平均(1月1日至2月28日)

| MAR-18 | 13.476923 |平均(1月1日至3月6日)

模式

  CREATE TABLE RAW_AVG
    ("Dayofmonth" date, "Numbervalue" int)
;

INSERT ALL 
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('01-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('02-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('03-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('04-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('05-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('06-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('07-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('08-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('09-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('10-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('11-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('12-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('13-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('14-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('15-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('16-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('17-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('18-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('19-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('20-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('21-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('22-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('23-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('24-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('25-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('26-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('27-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('28-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('29-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('30-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('31-Jan-2018', 12)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('01-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('02-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('03-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('04-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('05-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('06-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('07-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('08-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('09-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('10-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('11-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('12-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('13-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('14-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('15-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('16-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('17-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('18-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('19-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('20-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('21-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('22-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('23-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('24-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('25-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('26-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('27-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('28-Feb-2018', 15)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('01-Mar-2018', 14)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('02-Mar-2018', 14)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('03-Mar-2018', 14)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('04-Mar-2018', 14)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('05-Mar-2018', 14)
    INTO RAW_AVG ("Dayofmonth", "Numbervalue")
         VALUES ('06-Mar-2018', 14)
SELECT * FROM dual
;

答案 我使用下面的代码(修改了Avi先生代码)获得了预期的结果。  “ 6-MAR-18”用于模拟sysdate.today()

    with Ungroup_AVG AS
    (
    select    lastday,
    Round(Avg(totalpermonth) over (order by lastday rows between unbounded preceding and 
    Current row),6) as Valuespermonth
    from (
      select
      --last_day("Dayofmonth") lastday
      CASE WHEN
          "Dayofmonth" = '6-MAR-18' AND "Dayofmonth" < last_day('6-MAR-18' ) OR "Dayofmonth">=  trunc(last_day('6-MAR-18')-1, 'mm')
          THEN
          --to_date('6-MAR-18','DD-MON-YY')
           "Dayofmonth"
          ELSE
          last_day("Dayofmonth") 
          END lastday,
      Avg("Numbervalue") totalpermonth
      from RAW_AVG
      group by last_day("Dayofmonth"), "Dayofmonth") z  )
    ,
    Last_dayofMonth as(
      select max(lastday) as "DATEA" from Ungroup_AVG group by TRUNC(lastday, 'MM')
      )
    ,AVGZ as(  
      SELECT lastday,MAX(Valuespermonth) FROM Ungroup_AVG GROUP BY lastday,TRUNC(lastday, 'MM')
      )
    select M.* from Last_dayofMonth L
    JOIN
    AVGZ M on L."DATEA"= M.lastday
      ;

2 个答案:

答案 0 :(得分:1)

您可以像每月的滚动平均值一样获得输出。由于您具有按行排列的数据,因此您可以首先以相同的方式进行操作,获得每月平均值,然后获得全年滚动平均值。请注意,如果您一次进行全部均值(如您在Excel中所做的),然后在SQL中首先进行平均,则每月将需要一行。

With Cte as (select to_date('01-Jan-18', 'DD-MM-YY') Dayofmonth, 15 as Numbervalue 
from dual 
union all 
select to_date('02-Jan-18', 'DD-MM-YY') Dayofmonth, 23 as Numbervalue from dual 
union all 
select to_date('03-Jan-18', 'DD-MM-YY') Dayofmonth, 3 as Numbervalue from dual 
union all 
select to_date('04-Jan-18', 'DD-MM-YY') Dayofmonth, 22 as Numbervalue from dual 
union all 
select to_date('05-Jan-18', 'DD-MM-YY') Dayofmonth, 11 as Numbervalue from dual 
union all 
select to_date('06-Jan-18', 'DD-MM-YY') Dayofmonth, 33 as Numbervalue from dual 
union all 
select to_date('07-Jan-18', 'DD-MM-YY') Dayofmonth, 44 as Numbervalue from dual 
union all 
select to_date('01-Feb-18', 'DD-MM-YY') Dayofmonth, 33 as Numbervalue from dual 
union all 
select to_date('02-Feb-18', 'DD-MM-YY') Dayofmonth, 11 as Numbervalue from dual 
union all 
select to_date('03-Feb-18', 'DD-MM-YY') Dayofmonth, 22 as Numbervalue from dual 
union all 
select to_date('04-Feb-18', 'DD-MM-YY') Dayofmonth, 33 as Numbervalue from dual 
union all 
select to_date('05-Feb-18', 'DD-MM-YY') Dayofmonth, 44 as Numbervalue from dual 
union all 
select to_date('06-Feb-18', 'DD-MM-YY') Dayofmonth, 22 as Numbervalue from dual 
union all 
select to_date('07-Feb-18', 'DD-MM-YY') Dayofmonth, 11 as Numbervalue from dual 
union all 
select to_date('01-Mar-18', 'DD-MM-YY') Dayofmonth, 12 as Numbervalue from dual 
union all 
select to_date('02-Mar-18', 'DD-MM-YY') Dayofmonth, 23 as Numbervalue from dual
union all 
select to_date('03-Mar-18', 'DD-MM-YY') Dayofmonth, 34 as Numbervalue from dual 
union all 
select to_date('04-Mar-18', 'DD-MM-YY') Dayofmonth, 54 as Numbervalue from dual
union all 
select to_date('05-Mar-18', 'DD-MM-YY') Dayofmonth, 2 as Numbervalue from dual 
union all 
select to_date('06-Mar-18', 'DD-MM-YY') Dayofmonth, 12 as Numbervalue from dual)


select    lastday,
Round(Avg(totalpermonth) over (order by lastday rows between unbounded preceding and 
Current row),2) as Valuespermonth
from (
select  last_day(Dayofmonth) lastday, Avg(NumberValue) totalpermonth
from cte
group by last_day(Dayofmonth) ) z  ; 

说明:无界的前一行之间的行将占用所有前一行和当前行,并获得直到当前行的平均值。因此,对于2月,将需要1月平均和2月,而对于3月,将需要1月,2月和3月的平均值。

输出:

 LASTDAY    VALUESPERMONTH
 31-JAN-18  21.57
 28-FEB-18  23.36
 31-MAR-18  23.18

答案 1 :(得分:0)

没有真正知道您需要哪种方法:

SELECT
    TO_CHAR( order_month, 'MON-YY' )
  , order_avg
  , AVG( order_avg ) OVER () AS YTD_avg
FROM (
    SELECT
        TRUNC( "Date", 'MM' ) AS order_month
      , AVG( "NumberA" )      AS order_avg
    FROM RAW_AVG
    GROUP BY
        TRUNC( "Date", 'MM' )
    ORDER BY
        order_month
) d

或者,也许:

SELECT
    TO_CHAR( order_month, 'MON-YY' ) AS Label
  , order_avg
FROM (
    SELECT
        TRUNC( "Date", 'MM' ) AS order_month
      , AVG( "NumberA" )      AS order_avg
    FROM RAW_AVG
    GROUP BY
        TRUNC( "Date", 'MM' )
    ORDER BY
        order_month
) d
UNION ALL
SELECT
    'Total'
  , AVG( NumberA )
FROM RAW_AVG