Working With Temporary Views Using Common Table Expression in SQL Server 2005

CTEs and Temporary Tables

A CTE can be created using the WITH statement with the CTE name following it. You will find that temporary tables aren’t as convenient. For instance, unlike CTEs, temporary tables can be populated only after they have been created and not otherwise. Study the following syntax to note the difference:

CREATE TABLE #My_CTE
(
  LP money, SP money
)
   INSERT INTO #My_CTE
   (LP, SP)
        SELECT LP, LP * .95 FROM itemlist.item

Temporary tables as used in SQL 2000, allow them to be called repeatedly from within a statement, whereas in a Common Table Expression, it can be called immediately after stating it. Hence, if you write syntax similar to the following example, there won’t be any response to the CTE you call.

USE AdventureWorks
GO
    WITH MyCTE (LP, SP) AS
  (
   SELECT LP, LP * .95 FROM itemlist.item
    )
 SELECT * FROM itemlist.item
     SELECT * FROM My_CTE
  GO

Both a CTE and a temporary table can be called by name using the SELECT * statement.

CTEs and Derived Tables

Derived tables in SQL 2000 and CTEs in SQL 2005 are very similar. Derived tables serve in simple queries; however, they suffer from two drawbacks: they can be used only once, and you cannot refer to it by name. CTEs score over derived tables when it comes to complex statements. In fact, CTEs can efficiently handle simple queries too, since they can be rewritten as derived tables as shown below:

  SELECT * FROM
  (
     SELECT LP, (LP * .95) AS SP
        FROM itemlist.item
   )
  MyDerivedTable

Recursive Queries

A recursive query used in SQL Server 2005 refers to a recursive CTE. It allows you to set up arbitrary levels of queries on data that have a tree like structure (hierarchical), for instance, the employee reporting structure in an organization — something that was not possible in SQL 2000. You can either set the number of levels of recursion you want or leave them without any limit depending upon the query required.

Let us study the following example of reporting an organizational hierarchy where a initial subquery is set up to return only those records (employees) that report to the top management (represented by Mng_ID = null). If we limit the number of levels of recursion here, we will be excluding those employees who fall outside the defined chain of command. If we set no limit, no employee is excluded but there is a risk of an infinite recursion occurring if any employee happens to be reporting directly or indirectly to himself, like a director who is also an employee. In such cases, you can join the table to itself once for each level.

A recursive subquery is then set up by using the CTE name “DictRep” to append additional rows to the result set. The two are then connected by using the operator UNION ALL. The first or the initial subquery is nonrecursive and is processed first while the recursive query refers to the rows that were added in the previous cycle. Whenever iteration generates no new rows, recursion comes to a halt. Running the following syntax will display the result set that shows the reporting levels in the organization.

USE AdventureWorks ;
GO
WITH DictRep(Log_ID, Mng_ID, Emp_ID) AS
(
    SELECT Log_ID, Mng_ID, Emp_ID
    FROM HRs.Emp
    WHERE Mng_ID IS NULL
    UNION ALL
    SELECT e.Log_ID, e.Mng_ID, e.Emp_ID
            FROM HRs.Emp e
    INNER JOIN DictRep d
    ON e.Mng_ID = d.Emp_ID
)
SELECT * FROM DictRep ;
GO

The result set would be:

Log_ID

Emp_ID

Mng_ID

Ken0

109

NULL

David0

6

109

Terri0

12

109

Peter0

21

109

Jean0

42

109

Laura1

140

109

James1

148

109

Brain3

273

109

Stephen0

268

273

Amy0

284

273

Syed0

288

273

Jae0

290

288

Lynn0

285

284

Ranjit0

286

284

Rachel0

289

284

Micheal9

275

268

Recursive CTEs need an anchor member definition and a UNION ALL statement to generate appropriate results.

For all those who have so far been working with temporary tables and derived tables alone, Common Expression Tables are a good option to explore. Unlike recursive routines used in other languages, a recursive CTE can return multiple rows instead of one scalar value. It can handle complex queries and has a syntax that is easy to understand, read and write.

]]>

Leave a comment

Your email address will not be published.