As CTE’s são muito semelhantes às tabelas derivadas, mas com uma boa vantagem…
De acordo com o BOL a estrutura para uma CTE é:
1 2 3 4 5 |
WITH expression_name [ ( column_name [,...n] ) ] AS ( CTE_query_definition ) SELECT FROM expression_name; |
Uma comparação de uso entre uma tabela derivada e uma CTE:
Tabela derivada:
1 2 3 4 5 |
SELECT * FROM (SELECT Nome, Cidade FROM CLIENTES WHERE DataCadastro > '2011-01-01') AS CLI2011 |
Usando CTE:
1 2 3 4 5 6 |
;WITH CLI2011 AS ( SELECT Nome, Cidade FROM CLIENTES WHERE DataCadastro > '2011-01-01') SELECT * FROM CLI2011; |
Note o ‘;’ antes do WITH… Ele está lá por eu considerar uma boa prática, uma vez que sempre que você utilizar uma CTE, caso tenha alguma outra consulta antes, ela obrigatoriamente deve terminar com o ‘;’. Então, por via das dúvidas, sempre coloque ele antes do WITH, quando for usar uma CTE.
Até aí, nada demais, certo?
Mas a coisa melhora agora… quando falamos em múltiplas CTE’s x múltiplas tabelas derivadas
Se você precisa utilizar mais de uma tabela derivada e referenciar uma dentro de outra (aninhamento de tabelas), o código pode ficar terrível de ler, por mais bem documentado que ele seja. Um exemplo (bem esdrúxulo) usando aninhamento de tabelas derivadas:
1 2 3 4 5 6 7 8 9 10 11 |
SELECT * FROM ( SELECT Estado, SUM(Valor) AS Val FROM ( SELECT Estado, Valor FROM PEDIDOS ) AS PD1 GROUP BY Estado ) AS GRP_PD1 WHERE Estado = 'BA' |
Agora, a mesma consulta, usando CTE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
;WITH PD1 AS ( SELECT Estado, Valor FROM PEDIDOS ), GRP_PD1 AS ( SELECT Estado, SUM(Valor) AS Val FROM PD1 GROUP BY Estado ) SELECT Estado, Val FROM GRP_PD1 WHERE Estado = 'BA' |
Como podem ver, o código fica muio mais legível, mais fácil de entender…
Por agora era isso. Outra hora eu pretendo falar sobre as CTE’s Recursivas.
[]’s