Bearbeitet mit den neuesten Anforderungen.
Ihr Problem ist, dass Sie versuchen, den previous_avg zu erhalten, indem Sie versuchen, QTR und YEAR zu manipulieren. Ich verwende die RANK-Funktion und ordne die Daten so an, wie ich möchte. In den Verknüpfungen stelle ich sicher, dass die durchschnittliche Region =vorherige Region ist, und wenn ich das Jahr seit dem vorherigen Quartal außer Acht lasse, könnte das Q4 des Vorjahres für das durchschnittliche Jahr Q1 sein; So ist es sauberer.
--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