sql >> Databáze >  >> RDS >> Oracle

průměrný prodej za čtvrtletí s průměrným prodejem za předchozí čtvrtletí

Upraveno podle nejnovějších požadavků.

Váš problém je, že se pokoušíte získat předchozí_avg tím, že se pokoušíte manipulovat s QTR a YEAR. Používám funkci RANK a uspořádávám tak, jak chci data seřadit. Ve spojeních se ujišťuji, že Průměrný region =Předchozí region a bez ohledu na rok od předchozího čtvrtletí může být pro Průměrný rok Q1 Q4 předchozího roku; takhle je to čistší.

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


  1. Uživatelský alias Oracle DB

  2. Jak funguje SECOND() v MariaDB

  3. Tabulka MySQL Alter způsobuje Error:Neplatné použití hodnoty NULL

  4. Klauzule SQL OVER() – kdy a proč je užitečná?