如何在oracle 12c中查找前12个月连续四个月的平均值

时间:2018-07-27 06:53:07

标签: sql oracle select average oracle12c

我需要使用Oracle 12c找到连续四个月的前12个月

原始输出:

Month     Consumption
01/04/17  10000
01/05/17  10000
01/06/17  10000
01/07/17  13000
01/08/17  11000
01/09/17  12000
01/10/17  10000
01/11/17  12000 

示例:(预期输出)

Consecutive Months  Avg. of 4 Months Consumption
04/17 - 07/17         10750
05/17 - 08/17         11250
06/17 - 09/17         11750
07/17 - 10/17         12250
08/17 - 11/17         12750
09/17 - 12/17         13250
10/17 - 01/18         13750
11/17 - 02/18         14250
12/17 - 03/18         14750

2 个答案:

答案 0 :(得分:1)

尝试使用connect by level获取12个月的数据

然后group + avg获取预期数据

with CTE as (
    select 
        TO_DATE(TO_CHAR( ADD_MONTHS(sysdate ,- (level+3)),'YYYY/MM/')||'01','yyyy/mm/dd') sDate
        ,TO_DATE(TO_CHAR( ADD_MONTHS(sysdate ,- level),'YYYY/MM/')||'01','yyyy/mm/dd') eDate
        ,level from dual 
    connect by level <=12 
)
,CTE2 as (
  select * 
  from CTE T1
  left join T T2 on cast(T2."Month" as date) between T1.sDate and T1.eDate
)
select TO_CHAR(sDate,'MM/YY') || ' - ' || TO_CHAR(eDate,'MM/YY') as "Consecutive Months"
  ,round(avg("Consumption")) as "Avg. of 4 Months Consumption"
from CTE2
group by sDate,eDate
order by eDate

结果

| Consecutive Months | Avg. of 4 Months Consumption |
|--------------------|------------------------------|
|      04/17 - 07/17 |                        10750 |
|      05/17 - 08/17 |                        11000 |
|      06/17 - 09/17 |                        11500 |
|      07/17 - 10/17 |                        11500 |
|      08/17 - 11/17 |                        11250 |
|      09/17 - 12/17 |                        11333 |
|      10/17 - 01/18 |                        11000 |
|      11/17 - 02/18 |                        12000 |
|      12/17 - 03/18 |                       (null) |
|      01/18 - 04/18 |                       (null) |
|      02/18 - 05/18 |                       (null) |
|      03/18 - 06/18 |                       (null) |

测试DDL:

CREATE TABLE T
    ("Month" timestamp, "Consumption" int)
;

INSERT ALL 
    INTO T ("Month", "Consumption")
         VALUES ('01-Apr-2017 12:00:00 AM', 10000)
    INTO T ("Month", "Consumption")
         VALUES ('01-May-2017 12:00:00 AM', 10000)
    INTO T ("Month", "Consumption")
         VALUES ('01-Jun-2017 12:00:00 AM', 10000)
    INTO T ("Month", "Consumption")
         VALUES ('01-Jul-2017 12:00:00 AM', 13000)
    INTO T ("Month", "Consumption")
         VALUES ('01-Aug-2017 12:00:00 AM', 11000)
    INTO T ("Month", "Consumption")
         VALUES ('01-Sep-2017 12:00:00 AM', 12000)
    INTO T ("Month", "Consumption")
         VALUES ('01-Oct-2017 12:00:00 AM', 10000)
    INTO T ("Month", "Consumption")
         VALUES ('01-Nov-2017 12:00:00 AM', 12000)
SELECT * FROM dual
;

SQL Fiddle

答案 1 :(得分:1)

您可以使用avg的分析版本,并使用lag确保窗口确实有四个月的时间:

SELECT   * 
FROM     (SELECT LAG(mnth, 4) AS start_month,
                 mnth AS end_month,
                 AVG(consumption) OVER 
                    (ORDER BY mnth ROWS BETWEEN CURRENT ROW AND 4 PRECEDING) AS avg_consumption
          FROM   mytable) t
WHERE    start_month IS NOT NULL
ORDER BY 1 ASC