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 MaionHoje 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.
- Representando dados em XML no SQL ServerSQL Server
- Diferenças entre SEQUENCES x IDENTITY no Microsoft SQL Server 2012SQL
- Utilizando FILETABLE no SQL Server 2012SQL Server
- NHibernate com o Delphi Prism: Acessando um Banco de Dados SQL ServerVisual Studio
- Novidades no SQL Server Codinome DenaliSQL Server