Chegando ao SQL de outras linguagens de programação, a estrutura de uma consulta recursiva parece bastante estranha. Ande por ela passo a passo, e parece desmoronar.
Considere o seguinte exemplo simples:
CREATE TABLE #NUMS
(N BIGINT);
INSERT INTO #NUMS
VALUES (3), (5), (7);
WITH R AS
(
SELECT N FROM #NUMS
UNION ALL
SELECT N*N AS N FROM R WHERE N*N < 10000000
)
SELECT N FROM R ORDER BY N;
Vamos passar por isso.
Primeiro, o membro âncora é executado e o conjunto de resultados é colocado em R. Portanto, R é inicializado em {3, 5, 7}.
Em seguida, a execução cai abaixo do UNION ALL e o membro recursivo é executado pela primeira vez. Ele é executado em R (ou seja, no R que atualmente temos em mãos: {3, 5, 7}). Isso resulta em {9, 25, 49}.
O que isso faz com esse novo resultado? Ele anexa {9, 25, 49} ao {3, 5, 7} existente, rotula a união resultante R e continua com a recursão a partir daí? Ou redefine R para ser apenas esse novo resultado {9, 25, 49} e faz toda a união depois?
Nenhuma escolha faz sentido.
Se R agora for {3, 5, 7, 9, 25, 49} e executarmos a próxima iteração da recursão, terminaremos com {9, 25, 49, 81, 625, 2401} e teremos perdeu {3, 5, 7}.
Se R agora é apenas {9, 25, 49}, temos um problema de identificação incorreta. R é entendido como a união do conjunto de resultados do membro âncora e de todos os conjuntos de resultados do membro recursivo subsequentes. Enquanto {9, 25, 49} é apenas um componente de R. Não é o R completo que acumulamos até agora. Portanto, escrever o membro recursivo como selecionar R não faz sentido.
Eu certamente aprecio o que @Max Vernon e @Michael S. detalharam abaixo. Ou seja, que (1) todos os componentes são criados até o limite de recursão ou conjunto nulo e (2) todos os componentes são unidos. É assim que eu entendo a recursão do SQL para realmente funcionar.
Se estivéssemos redesenhando o SQL, talvez aplicássemos uma sintaxe mais clara e explícita, algo como isto:
WITH R AS
(
SELECT N
INTO R[0]
FROM #NUMS
UNION ALL
SELECT N*N AS N
INTO R[K+1]
FROM R[K]
WHERE N*N < 10000000
)
SELECT N FROM R ORDER BY N;
Mais ou menos como uma prova indutiva em matemática.
O problema com a recursão do SQL como está atualmente é que ele é escrito de uma maneira confusa. A maneira como está escrito diz que cada componente é formado pela seleção de R, mas isso não significa que o R completo que foi (ou, parece ter sido) construído até agora. Significa apenas o componente anterior.