Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Venda média do trimestre com venda média do trimestre anterior


Editado com os requisitos mais recentes.

Seu problema é que você está tentando obter o previous_avg tentando manipular QTR e YEAR. Estou usando a função RANK, ordenando a maneira como quero que os dados sejam classificados. Nas junções estou me certificando de que Região Média =Região Anterior e desconsiderando o ano desde o trimestre anterior poderia ser Q4 do ano anterior para o ano Médio Q1; é mais limpo assim.
    --Build the test table
    IF OBJECT_ID('SALES','U') IS NOT NULL
        DROP TABLE SALES

    CREATE TABLE SALES
    (
          Region  VARCHAR(255)
        , Product VARCHAR(10)
        , [Year]  INT
        , QTR     INT
        , [Month] VARCHAR(19)
        , Sales   DECIMAL(19,4)
    );

    INSERT SALES
    VALUES
         ('NORTH', 'P1', 2015, 1, 'JAN', 1000)
        ,('NORTH', 'P1', 2015, 1, 'FEB', 2000)
        ,('NORTH', 'P1', 2015, 1, 'MAR', 3000)
        ,('NORTH', 'P1', 2015, 2, 'APR', 4000)
        ,('NORTH', 'P1', 2015, 2, 'MAY', 5000)
        ,('NORTH', 'P1', 2015, 2, 'JUN', 6000)
        ,('NORTH', 'P1', 2015, 3, 'JUL', 7000)
        ,('NORTH', 'P1', 2015, 3, 'AUG', 8000)
        ,('NORTH', 'P1', 2015, 3, 'SEP', 9000)
        ,('NORTH', 'P1', 2015, 4, 'OCT', 1000)
        ,('NORTH', 'P1', 2015, 4, 'DEC', 4000)
        ,('NORTH', 'P1', 2015, 4, 'NOV', 2000)
        ,('NORTH', 'P3', 2015, 1, 'FEB', 1000)
        ,('NORTH', 'P3', 2015, 1, 'FEB', 9000)
        ,('NORTH', 'P3', 2015, 2, 'APR', 2000)
        ,('NORTH', 'P3', 2015, 3, 'JUL', 8000)
        ,('NORTH', 'P1', 2016, 1, 'MAR', 3000)
        ,('NORTH', 'P1', 2016, 1, 'FEB', 1000)
        ,('NORTH', 'P1', 2016, 1, 'JAN', 2000)
        ,('SOUTH', 'P1', 2015, 1, 'JAN', 2000)
        ,('SOUTH', 'P1', 2015, 1, 'FEB', 3000)
        ,('SOUTH', 'P1', 2015, 1, 'JAN', 4000)
        ,('SOUTH', 'P2', 2015, 1, 'MAR', 1000)
        ,('SOUTH', 'P2', 2015, 1, 'JAN', 8000)
        ,('SOUTH', 'P2', 2015, 1, 'FEB', 9000)
        ,('SOUTH', 'P2', 2015, 2, 'JUN', 9000)
        ,('SOUTH', 'P2', 2015, 2, 'MAY', 8000)
        ,('SOUTH', 'P2', 2015, 2, 'APR', 2000)
        ,('SOUTH', 'P2', 2015, 3, 'SEP', 4000)
        ,('SOUTH', 'P2', 2015, 3, 'AUG', 2000)
        ,('SOUTH', 'P2', 2015, 3, 'JUL', 1000)
        ,('SOUTH', 'P2', 2015, 4, 'NOV', 2000)
        ,('SOUTH', 'P2', 2015, 4, 'DEC', 1000)
        ,('SOUTH', 'P2', 2015, 4, 'OCT', 5000)
        ,('SOUTH', 'P3', 2015, 3, 'AUG', 9000)
        ,('SOUTH', 'P3', 2015, 4, 'OCT', 1000)
        ,('SOUTH', 'P3', 2015, 4, 'NOV', 3000)
        ,('SOUTH', 'P2', 2016, 1, 'JAN', 2000)
        ,('SOUTH', 'P2', 2016, 1, 'JAN', 4000);


    --CTE TO CAPTURE AVG SALES BY REGION, PRODCUT, YEAR, QTR;  OMIT PRODUCT IF YOU WANT STRAIGHT UP QUARTER AVG, REGARDLESS OF PRODCUCT
    WITH cteAvgSales AS
    (
        SELECT Region, Product, [Year], QTR, AVG(Sales) current_avg
            , RANK() OVER(ORDER BY Region, Product, [Year], QTR) AS RNK
        FROM SALES
        GROUP BY Region, Product, [Year], QTR
    )
    SELECT s.Region, s.Product, s.[Year] AS [year], s.QTR AS [quarter], s.[Month], s.Sales, a.current_avg, p.current_avg AS previous_avg
    FROM SALES s
        INNER JOIN cteAvgSales a ON a.Region = s.Region
            AND a.Product = s.Product
            AND a.[Year]  = s.[Year]
            AND a.QTR = s.QTR
        LEFT JOIN cteAvgSales p ON p.Region = a.Region
            AND p.Product = s.Product
            AND p.RNK=a.RNK-1
    ORDER BY s.Region, s.Product, s.[Year], s.QTR