Overview

WITH Sales
(
	[SalesPersonID],
	[SalesOrderID], 
	[SalesYear]
)
AS
(
    SELECT 
			[SalesPersonID], 
			[SalesOrderID],
			YEAR([OrderDate])
    FROM Sales.SalesOrderHeader
    WHERE SalesPersonID IS NOT NULL
)
SELECT 
	[SalesPersonID],
	COUNT([SalesOrderID]) AS [TotalSales], 
	[SalesYear]
FROM [Sales]
GROUP BY [SalesYear], [SalesPersonID]
ORDER BY [SalesYear], [SalesPersonID];

Multiple CTE in a Query

WITH Sales_CTE (SalesPersonID, TotalSales, SalesYear)  
AS  
(  
    SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, YEAR(OrderDate) AS SalesYear  
    FROM Sales.SalesOrderHeader  
    WHERE SalesPersonID IS NOT NULL  
       GROUP BY SalesPersonID, YEAR(OrderDate)
),
Sales_Quota_CTE (BusinessEntityID, SalesQuota, SalesQuotaYear)  
AS  
(  
       SELECT BusinessEntityID, SUM(SalesQuota)AS SalesQuota, YEAR(QuotaDate) AS SalesQuotaYear  
       FROM Sales.SalesPersonQuotaHistory  
       GROUP BY BusinessEntityID, YEAR(QuotaDate)  
)  
SELECT SalesPersonID, 
	SalesYear,
	FORMAT(TotalSales,'C','en-us') AS TotalSales,
	SalesQuotaYear,
	FORMAT (SalesQuota,'C','en-us') AS SalesQuota,
	FORMAT (TotalSales -SalesQuota, 'C','en-us') AS Amt_Above_or_Below_Quota
FROM Sales_CTE  
JOIN Sales_Quota_CTE 
	ON Sales_Quota_CTE.BusinessEntityID = Sales_CTE.SalesPersonID  
    AND Sales_CTE.SalesYear = Sales_Quota_CTE.SalesQuotaYear  
ORDER BY SalesPersonID, SalesYear;

Recursive Queries Using CTE

WITH [NumberList]
AS
(
	SELECT 1 AS [Num] -- Anchor member
	UNION ALL
  SELECT [Num] + 1 -- Recursive Member
	FROM [NumberList]
	WHERE [Num] < 50 -- Terminator
)
SELECT [Num]
FROM [NumberList]
OPTION (MAXRECURSION 50);

Find Product Component Level using Recursive CTE

WITH Parts
(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) 
AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty, b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800 AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty, [bom].EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS [bom]
    INNER JOIN Parts AS p
        ON [bom].ProductAssemblyID = p.ComponentID
        AND [bom].EndDate IS NULL
)
SELECT AssemblyID, ComponentID, [Name], [PerAssemblyQty], EndDate,
        ComponentLevel 
FROM Parts AS p
INNER JOIN Production.Product AS pr
    ON p.ComponentID = pr.ProductID
ORDER BY ComponentLevel, AssemblyID, ComponentID;

Update Table Using Recursive CTE

WITH Parts
(
	AssemblyID,
	ComponentID,
	PerAssemblyQty,
	EndDate,
	ComponentLevel
)
AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
        b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800
          AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
        bom.EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS bom 
        INNER JOIN Parts AS p
        ON bom.ProductAssemblyID = p.ComponentID
        AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0;

Guidelines for Creating and Using CTE