In this article, we will take a look at the concept of Common Table Expressions in SQL Server 2005 along with sample code on their usage. A Common Table Expression is defined by MS as a "Temporary Named Resultset".
CTEs provide functionality similar to Views, except the definition of the CTE is not stored in the SQL Server metadata.
CTEs allow creating a modular solution which functions similar to a temporary table and can be referenced within functions, stored procedures, views, within other CTEs and also recursively..
Among the advantages of CTEs is the capability to reference the resulting "table" (resultset) multiple times in the same statement. CTEs can be used as part of Select/Insert/Update/Delete statements.
CTEs provide a clean solution for problems which require recursive logic and the benefits of CTEs become the most apparent in these cases.
CTE Lifetime/Scope: CTEs are not "persisted" and have to be used in a Select/Update/Delete/Insert statement following the CTE definition.
Data resulting from the CTE retrieved and filtered on the Asset Status and the aggregated AuditCount .
Code Listing 1: Simple CTE
WITH CTE_Assets (Asset_Id, AssetTag, Status, LastAudited, AuditCount)
AS
(
SELECT Assets.AssetId, Assets.AssetTag, Assets.Status,
MAX(AssetAudit.Audit_Date), COUNT(AssetsAudit.AuditId)
FROM Assets LEFT JOIN AssetAudit
ON Assets.AssetId = AssetAudit.AssetId
GROUP BY Assets.AssetId, Assets.AssetTag, Assets.Status
)
SELECT AssetId, AssetTag, Status, LastAudited, AuditCount
FROM CTE_Assets
WHERE Status = 'In Use' and AuditCount > 0
Figure 1: Results of Code Listing 1: Simple CTE

Usage Scenario: Join CTEs
The following code sample defines 2 CTEs - cte_Assets and cte_Locations within the same WITH statement. Data is retrieved by joining the 2 CTEs.
Code Listing 2: Join multiple CTEs
WITH CTE_Assets (Asset_Id, AssetTag, Status, LocationID)
AS
( SELECT Assets.Asset_Id, Assets.AssetTag, Assets.Status
FROM Assets
),
cte_locations (LocationID, LocationCode, LocationDesc) as
(
SELECT LocationID, LocationCode, LocationDesc
FROM Locations
)
SELECT Asset_Id, AssetTag, Status, LocationCode, LocationDesc
FROM CTE_Assets INNER JOIN CTE_Locations
ON CTE_Assets.LocationID = CTE_Locations.LocationID
WHERE CTE_Assets.Status = 'In Use'


Join the conversation! Your thoughts help the community grow.