Nunca uso CTE com recursão. Eu estava lendo um artigo sobre isso. Este artigo mostra informações do funcionário com a ajuda do servidor Sql CTE e recursão. Basicamente, mostra as informações dos funcionários e de seus gerentes. Não consigo entender como essa consulta funciona. Aqui está a consulta:
WITH
cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
AS
(
SELECT EmployeeID, FirstName, LastName, ManagerID, 1
FROM Employees
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
r.EmpLevel + 1
FROM Employees e
INNER JOIN cteReports r
ON e.ManagerID = r.EmpID
)
SELECT
FirstName + ' ' + LastName AS FullName,
EmpLevel,
(SELECT FirstName + ' ' + LastName FROM Employees
WHERE EmployeeID = cteReports.MgrID) AS Manager
FROM cteReports
ORDER BY EmpLevel, MgrID
Aqui estou postando sobre como a saída está sendo exibida:
Só preciso saber como isso mostra o gerente primeiro e depois o subordinado em um loop. Acho que a primeira instrução sql dispara apenas uma vez e retorna todos os ids de funcionários.
E a segunda consulta dispara repetidamente, consultando o banco de dados no qual o funcionário existe com o ID de gerente atual.
Explique como a instrução sql é executada em um loop interno e também me diga a ordem de execução do sql. Obrigado.
MINHA 2ª fase de questão
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
Q 1) como o valor de N está sendo incrementado? se o valor for atribuído a N todas as vezes, o valor N pode ser incrementado, mas apenas na primeira vez que o valor N foi inicializado.
Q 2) CTE e recursão das relações com os funcionários:
No momento em que acrescento dois gerentes e mais alguns funcionários sob o segundo gerente, é onde o problema começa.
Desejo exibir o primeiro detalhe do gerente e nas próximas linhas apenas os detalhes do funcionário que se relacionam ao subordinado desse gerente.
Suponha
ID Name MgrID Level
--- ---- ------ -----
1 Keith NULL 1
2 Josh 1 2
3 Robin 1 2
4 Raja 2 3
5 Tridip NULL 1
6 Arijit 5 2
7 Amit 5 2
8 Dev 6 3
Desejo exibir os resultados dessa forma com expressões CTE. Diga-me o que devo modificar em meu sql que forneci aqui para obter as relações gerente-funcionário. Obrigado.
Quero que a saída seja assim:
ID Name MgrID nLevel Family
----------- ------ ----------- ----------- --------------------
1 Keith NULL 1 1
3 Robin 1 2 1
2 Josh 1 2 1
4 Raja 2 3 1
5 Tridip NULL 1 2
7 Amit 5 2 2
6 Arijit 5 2 2
8 Dev 6 3 2
Isso é possível...?
Gostaria de esboçar um breve paralelo semântico para uma resposta já correta.
Em termos 'simples', um CTE recursivo pode ser semanticamente definido como as seguintes partes:
1: A consulta CTE. Também conhecido como ANCHOR.
2: A consulta CTE recursiva na CTE em (1) com UNION ALL (ou UNION ou EXCEPT ou INTERSECT) para que o resultado final seja retornado de acordo.
3: A condição de canto / terminação. Que é por padrão quando não há mais linhas / tuplas retornadas pela consulta recursiva.
Um pequeno exemplo que tornará a imagem clara:
Explicação: A primeira consulta CTE retorna os fornecedores de base (como folhas) que não fornecem para nenhum outro fornecedor diretamente (-1)
A consulta recursiva na primeira iteração obtém todos os fornecedores que fornecem aos fornecedores retornados pela ANCHOR. Este processo continua até que a condição retorne tuplas.
UNION ALL retorna todas as tuplas sobre o total de chamadas recursivas.
Outro bom exemplo pode ser encontrado aqui .
PS: Para que um CTE recursivo funcione, as relações devem ter uma condição hierárquica (recursiva) para funcionar. Ex: elementId = elementParentId .. você entendeu.
fonte
O processo de execução é realmente confuso com CTE recursiva, encontrei a melhor resposta em https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx e o resumo do processo de execução de CTE é como abaixo.
A semântica da execução recursiva é a seguinte:
fonte
fonte