Banco de Dados - SQL Server

Self-Join X CTE (Common Table Expression)

Neste artigo irei fazer uma comparação entre Self-Join e CTE. Iremos ver também porque utilizar o CTE quando falamos de recursão e como podemos utilizar este novo recurso.

por Rafaela Sampaio Maion



Hoje iremos falar sobre CTE – Common Table Expression X SelfJoin.

O CTE é um recurso desde o SQL Server 2005. Se compararmos o código do Self-Join com o CTE , até parece complicado (Rs), mas ao decorrer do Post, veremos que é fácil.

Antes de mais nada, Self Join é quando utilizamos a mesma tabela no FROM e no JOIN. É normal fazermos isso quando queremos listar todos os funcionários e seus superiores. Antes do SQL Server 2005, esta era uma das forma que conseguíamos fazer esta junção.

SELECT E.EmployeeKey,

e.FirstName + "" + E.LastName as "Employee Name",

3

ds.FirstName + "" + ds.LastName as "Supervisor Name"

4

FROM DimEmployee e

5

INNER JOIN DimEmployee ds ON e.ParentEmployeeKey = ds.EmployeeKey

6

ORDER BY e.EmployeeKey

Com esta query consigo pegar os funcionários e quem é seu supervisor.

Ao decorrer do Post, iremos ver várias maneiras da utilização do CTE. Lembrando que podemos utilizar no escopo de SELECT, INSERT, DELETE, MERGE ou DELETE.

Uma CTE pode se auto referenciar (CTE recursiva) e pode ser referenciada várias vezes na mesma query.

Sintaxe:

WITH expression_name [ ( column_name [,...n] ) ]

AS

3

( CTE_query_definition )

Vou dar um exemplo simples da utilização:

WITH CTE_Simples (Id, Nome) AS

(

SELECTId, Nome FROM Funcionario

)

SELECT * FROM CTE_Simples

ou até mesmo

WITH CTE_Simples (Id, Nome) AS

(

SELECT 1, "Rafaela"

)

SELECT * FROM CTE_Simples

Simples não é mesmo ??? Claro, quando pensamos na utilização do CTE, pensamos em recursividade. Onde eu preciso chamar a minha CTE várias vezes, e isso cai no caso do exemplo que dei sobre Self-Join.

Vamos então utilizar o exemplo do Self-Join utilizando CTE.

Para trabalhar com CTE recursiva (Recursive CTE), teremos uma query inicial, chamada de query âncora e uma segunda query que é liga a âncora, através do UNION ALL.

WITH Employee_CTE (employeeKey,Level, EmployeeName) AS

(

SELECT e.EmployeeKey, 1, e.FirstName + "" + E.LastName as Name

FROM DimEmployee e

WHERE e.ParentEmployeeKey IS NULL

UNION ALL

SELECT e.EmployeeKey, cte.level + 1, e.FirstName + " " + E.LastName AS Name

FROM DimEmployee e

INNER JOIN Employee_CTE cte ON E.ParentEmployeeKey = cte.employeeKey

)

SELECT * FROM Employee_CTE

Se executarmos as duas querys (Self-Join e CTE) o Execute Plan tratá os seguintes custos:

· Self-Join – 0.0642

· CTE – 0.0249.

Claro, temos que considerar que a tabela que estou utilizando tem apenas 296, mas a intensão é mostrar que temos um ganho de performance utilizando o CTE.

Bom espero que tenham gostado, e nos vemos na próxima.

Rafaela Sampaio Maion

Rafaela Sampaio Maion - MCTS SQL Server 2008. Formada em Sistema de Informação pela Faculdade Politécnica de Jundiaí e Pós-Graduada em Gestão de Projetos. Trabalha com tecnologia desde 2003, neste tempo participou na elaboração de projetos críticos com tecnologia Microsoft para grandes clientes do setor financeiro, seguros e de manufatura. Atualmente presta serviços de consultoria e ministra treinamentos SQL Server. Periodicamente escreve no blog: http://www.webdesenvolvimento.net/ e no http://rafinhagsampaio.spaces.live.com/default.aspx?sa=414559083