A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.
Check if the next query gives the results and can be adjusted:
;
with MonthlySales as
(
select d.CalendarYear, d.MonthNumberOfYear, s.ProductKey, sum(s.SalesAmount) as SalesAmount
from FactInternetSales s
inner join DimDate d on d.DateKey = s.OrderDateKey
group by d.CalendarYear, d.MonthNumberOfYear, s.ProductKey
)
select ms.CalendarYear, ms.MonthNumberOfYear,
p.EnglishProductName, pc.EnglishProductCategoryName, psc.EnglishProductSubcategoryName,
ms.SalesAmount as SalesAmount,
isnull(pms.SalesAmount, 0) as SalesAmountPreviousYear
from MonthlySales ms
inner join DimProduct p on p.ProductKey = ms.ProductKey
inner join DimProductSubcategory psc on psc.ProductSubcategoryKey = p.ProductSubcategoryKey
inner join DimProductCategory pc on pc.ProductCategoryKey = psc.ProductCategoryKey
left join MonthlySales pms on pms.ProductKey = ms.ProductKey and pms.CalendarYear = ms.CalendarYear-1 and pms.MonthNumberOfYear = ms.MonthNumberOfYear
order by CalendarYear, ms.MonthNumberOfYear, p.EnglishProductName
Use inner join instead of left join if you are only interested in products that have current and previous year sales.