;with TestCTE as (select * from Purchasing.PurchaseOrderHeader where OrderDate between '1-1-2008' and '3-31-2008' ) select * from TestCTE where ShipMethodID = 1At the surface one might initially think (and I first thought this when I started working with CTEs) that somewhere, for a brief period of time, there's some "temp something" called TestCTE...either in server memory, or in temp db....that the rows reflecting the orders for the first quarter here are stored "somewhere"
;with TestCTE as (select * from Purchasing.PurchaseOrderHeader where OrderDate between '1-1-2008' and '3-31-2008' )....I'd actually get an error message! Here's why....a common table expression is (in this situation) "syntax sugar" for a derived table subquery...with the subquery defined one line of code before, for a bit of clarity. If we define a CTE but don't use it, SQL Server views it as incomplete...it needs the subsequent line of code that actually defines what we will do with the CTE. So when we say...
;with TestCTE as (select * from Purchasing.PurchaseOrderHeader where OrderDate between '1-1-2008' and '3-31-2008' ) select * from TestCTE where ShipMethodID = 1It's (for all intents and purposes) the same as saying the following, which is a derived table subquery
select * from (select * from Purchasing.PurchaseOrderHeader where OrderDate between '1-1-2008' and '3-31-2008' ) TempList where ShipMethodID = 1So....it's not a temp table with a short life....it's basically a derived table subquery, placed above the line of code that uses it. Some developers find the syntax a bit easier, while older SQL developers (prior to SQL 2005) prefer the older style derived table syntax.
;with POSales as ( select ShipMethodID, sum(TotalDue) as POTotal from Purchasing.PurchaseOrderHeader group by ShipMethodID) , -- note the 2 CTEs, separated by a comma SOSales as (Select ShipMethodID, sum(TotalDue) as SOTotal from Sales.SalesOrderHeader group by ShipMethodID) select ShipMethod.Name, POSales.POTotal, Sosales.SOTotal from Purchasing.ShipMethod left outer join POSales on ShipMethod.ShipMethodID = POSales.ShipMethodID left outer join SOSales on ShipMethod.ShipMethodID = SOSales.ShipMethodIDThe "old-style" way using derived table subqueries will produce the same execution plan, and "usually" run in about the same amount of time. So here, the code for the two CTEs are now "in-line", instead of defined above. But both examples are treated as one execution.
select ShipMethod.Name, POSales.POTotal, Sosales.SOTotal from Purchasing.ShipMethod left outer join ( select ShipMethodID, sum(TotalDue) as POTotal from Purchasing.PurchaseOrderHeader group by ShipMethodID) POSales on ShipMethod.ShipMethodID = POSales.ShipMethodID left outer join ( Select ShipMethodID, sum(TotalDue) as SOTotal from Sales.SalesOrderHeader group by ShipMethodID) SOSales on ShipMethod.ShipMethodID = SOSales.ShipMethodID