This is part of the series of posts that I am running under the title "Under Appreciated Features of SQL Server". The series has been inspired by Andy Warren's editorial on SQLServerCentral.com.
Did you ever wonder if you could create a temporary result set and use that within a single SELECT, INSERT, UPDATE or DELETE statement? I bet you have, and before SQL Server 2005 came along, I am sure that you used either sub-queries, cursors or temporary tables to achieve the desired results.
Starting SQL Server 2005, we have a much better, and much more efficient method of achieving this - the common table expression, or the CTE. Much has been written about CTEs and their benefits, and hence I will be mostly presenting a summary of all the great articles and posts on the topic that I have chanced upon till date:
- An introduction to CTEs - http://www.simple-talk.com/content/article.aspx?article=260
- The things that you can do with a CTE - http://msdn.microsoft.com/en-us/library/ms175972.aspx
- A few data points on CTE - http://msdn.microsoft.com/en-us/magazine/cc163346.aspx#S3
Something interesting – CTE in a CREATE VIEW statement
Yes, CTEs can be used in a CREATE VIEW statement as is demonstrated by the queries below:
CREATE VIEW vSalesCTE
-- Define the CTE expression name and column list.
WITH Sales_CTE (SalesPersonID, SalesOrderID, SalesYear)
-- Define the CTE query.
SELECT SalesPersonID, SalesOrderID, YEAR(OrderDate) AS SalesYear
WHERE SalesPersonID IS NOT NULL
SELECT Sales_CTE.SalesPersonID, Sales_CTE.SalesOrderID, Sales_CTE.SalesYear
--Use the VIEW containing a CTE
SELECT vcte.SalesPersonID, COUNT(vcte.SalesOrderID) AS TotalSales, vcte.SalesYear
FROM vSalesCTE vcte
GROUP BY vcte.SalesYear, vcte.SalesPersonID
ORDER BY vcte.SalesPersonID, vcte.SalesYear
Don’t overestimate CTEs – don’t use them multiple times within the same query
As is the case with everything, CTEs in excess can also cause more harm than good. CTEs are more of “expandable” blocks of code, and hence, if you use them more than once in a query, you will end up with performance issues. This is because the entire data set is populated the number of times a CTE is used. For cases where you need to use the same data set again and again, use temporary tables or table variables instead.
I hope that CTE’s opened up a whole new programming paradigm for all. If you have not started experimenting with CTEs, I recommend that you start doing so – it will be fun.
Until we meet next time,
Be courteous. Drive responsibly.