avg sale of quarter with previous quarter avg sale

前端 未结 3 2014
北荒
北荒 2021-01-16 08:09

I have a table one in which there are various attribute like region product,year,qtr,month,sale. I have to calculate the avg_qtr sale of each product having same region and

3条回答
  •  悲&欢浪女
    2021-01-16 08:51

    Edited with the latest requirements.

    Your problem is that you are trying to get the previous_avg by trying to manipulate QTR and YEAR. I'm using the RANK function, ordering the way I want the data ranked. In the joins I'm making sure that Average Region = Previous Region and disregarding year since the previous quarter could be Q4 of the Previous year for Average year Q1; it's cleaner this way.

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

提交回复
热议问题