Take this query:
WITH OrderAmounts AS (
SELECT OD.OrderID, SUM(OD.Quantity * OD.UnitPrice) AS Amount
FROM dbo.[Order Details] OD
GROUP BY OD.OrderID
)
SELECT O.OrderID, C.CustomerID, C.CustomerName, C.City, OA.Amount
FROM dbo.Orders O
JOIN dbo.Customers C ON O.CustomerID = C.CustomerID
JOIN OrderAmounts OA ON O.OrderID = OA.OrderID
WHERE O.OrderDate = '19970421'
ORDER BY O.OrderID;
Logically, we are saying "Compute the sum of all orders in the database and join that result to the Orders table". But most likely the optimizer will see that is sufficient to compute the some for the orders on the given day.
Now consider:
CREATE TABLE #OrderAmounts (OrderID int NOT NULL PRIMARY KEY,
Amount decimal(20,2) NOT NULL);
INSERT #OrderAmounts (OrderID, Amount)
SELECT OD.OrderID, SUM(OD.Quantity * OD.UnitPrice) AS Amount
FROM dbo.[Order Details] OD
GROUP BY OD.OrderID;
SELECT O.OrderID, C.CustomerID, C.CustomerName, C.City, OA.Amount
FROM dbo.Orders O
JOIN dbo.Customers C ON O.CustomerID = C.CustomerID
JOIN #OrderAmounts OA ON O.OrderID = OA.OrderID
WHERE O.OrderDate = '19970421'
ORDER BY O.OrderID;
Logically, this is perfectly equivalent to the query above. However, since SQL Server does not perform optimizations across table, this time the totals for all orders will be computed and stored in the temp table. But it would be perfectly legal if it decided to ignore the temp table and shortcut in the same way as in the CTE query.