Oracle
 sql >> Database >  >> RDS >> Oracle

vendita media del trimestre con vendita media del trimestre precedente

Modificato con gli ultimi requisiti.

Il tuo problema è che stai cercando di ottenere il precedente_avg cercando di manipolare QTR e YEAR. Sto usando la funzione RANK, ordinando il modo in cui voglio che i dati siano classificati. Nei join mi sto assicurando che Regione media =Regione precedente e ignorando l'anno dal trimestre precedente potrebbe essere il quarto trimestre dell'anno precedente per l'anno medio Q1; è più pulito in questo modo.

    --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