Exemplo:
SET NOCOUNT ON;
SET IMPLICIT_TRANSACTIONS ON;
CREATE TABLE MyTable (MyID INT PRIMARY KEY);
GO
INSERT MyTable (MyID)
VALUES (11), (22), (33), (44), (55);
PRINT 'Test MyCTE:';
WITH MyCTE
AS (
SELECT *, ROW_NUMBER()OVER(ORDER BY MyID) AS RowNum
FROM MyTable
)
SELECT *
FROM MyCTE crt
LEFT JOIN MyCTE prev ON crt.RowNum=prev.RowNum+1;
ROLLBACK;
Se você executar o script anterior no SSMS (pressione
Ctrl+M
-> Plano de Execução Real) então você obterá este plano de execução para a última consulta: Neste caso, o CTE é executado uma vez para
crt
alias e cinco (!) vezes para prev
alias, uma vez para cada linha de crt
. Então, a resposta para esta pergunta
é
both
:uma vez por consulta (crt
) e uma vez por linha (prev
:uma vez para cada para de crt
). Para otimizar esta consulta, para começar,1) Você pode tentar armazenar os resultados do CTE (
MyCTE
ou Query
) em uma variável de tabela ou em uma tabela temporária 2) Defina a chave primária desta tabela como sendo a(s) coluna(s) de junção,
3) Reescreva a consulta final para usar essa variável de tabela ou tabela temporária.
Claro, você pode tentar reescrever a consulta final sem essa autojunção entre CTE.