CTE's Recursivas

09/10/2009 - 03:46 por alex | Informe spam
Hola , tengo una duda con respecto a las CTE's recursivas. El ejemplo que
sale en books online al ejecutarlo los resultados comienzan ordenados por la
columna LEVEL de menor a mayor 0 1 2 3 4 pero en cierto punto comienza a
descender como 0 1 2 3 4 3 3 2, o sea no estan ordenados de menor a mayor
todo el tiempo que es como se supone que trabaja haciendo UNION ALL a todos
los resultados parciales. Alguien me puede ayudar a comprender esto?
El ejemplo de books online (el ultimo WHERE lo elimine para que salgan todos
los resultados:

USE AdventureWorks;
GO
WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
AS
(
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
0 AS Level
FROM HumanResources.Employee AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL
WHERE ManagerID IS NULL
UNION ALL
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
Level + 1
FROM HumanResources.Employee AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.ManagerID = d.EmployeeID
)
SELECT ManagerID, EmployeeID, Title, Level
FROM DirectReports

Preguntas similare

Leer las respuestas

#6 alex
09/10/2009 - 23:19 | Informe spam
una vez mas gracias por tus comentarios esclarecedores, creo que ya
comprendo, al parecer el inner join no esta trabajando como un inner join
comun porque si fuera asi pues cada iteracion devolveria todos los hijos de
todos los padres cada vez. Al parecer el inner join devuelve solo uno hijo a
la vez y sigue por esa rama del arbol hasta que no hay mas, y solo entonces
pasa al hijo siguiente.

saludos,
alejandro.

"Carlos M. Calvelo" wrote in message
news:wn0n1solvgqk$.cdqymegh6bfz$
Hola Alejandro,

On Fri, 9 Oct 2009 15:57:14 -0400, alex wrote:

hola carlos, gracias por responder y entiendo lo que dices de que lo
principal es lo que hace y no como lo hace. el problema es que el ejemplo
de
books online viene con descripcion detallada de como lo hace pero la
explicacion no esta completa porque usan un WHERE dp.GroupName =
N'Research
and Development' OR Level = 0; y esto filtra los resultados por GroupName
y
entonces sale todo ordenado del LEVEL 0 al LEVEl 4.
Mi gran duda es que el como lo hace al parecer es simple pues el INNER
JOIN
recursivo automaticamente me saca TODOS los hijos de todos los PADRES
del
resultado anterior, o sea el inner join de la tabla de
HumanResources.Employee con la CTE me va a devolver TODOS los empleados
cuyo
manager esta en la CTE y luego recursivamente hace lo mismo con los
nuevos
resultados.
Entonces como es posible que por ejemplo todos los LEVEL 3 no salgan
juntos
pues obligatoriamente tienen que tener un manager en LEVEL 2, o sea
deberian
salir todos los level 3 juntos y todos los level 4 juntos y asi
sucesivamente.




Si miras el ejemplo que te he puesto, en la tercer y cuarta línea del
resultado saca los descendientes directos del último director, no de todos
los directores. En las linaas 5 y 6 están los descendientes directos del
último jefe del último director. Las líneas 7 y 8 son los descendientes
directos del penúltimo jefe del último director.
Las líneas 8 y 9 son los descendientes directos del penúltimo director
(aquí vuelve a reaparecer el nivel 2!), etc, etc.

Pero tu asumes que "el INNER JOIN recursivo automaticamente me saca TODOS
los hijos de todos los PADRES del resultado anterior", y eso no es verdad.
Por eso te dije que analizaras bien el ejemplo que te puse, que es
mas sencillo que el que estas estudiando ahora.

Saludos,
Carlos
Respuesta Responder a este mensaje
#7 Carlos M. Calvelo
09/10/2009 - 23:56 | Informe spam
Hola Alejandro,

On Fri, 9 Oct 2009 17:19:37 -0400, alex wrote:

una vez mas gracias por tus comentarios esclarecedores, creo que ya
comprendo, al parecer el inner join no esta trabajando como un inner join
comun porque si fuera asi pues cada iteracion devolveria todos los hijos de
todos los padres cada vez. Al parecer el inner join devuelve solo uno hijo a
la vez y sigue por esa rama del arbol hasta que no hay mas, y solo entonces
pasa al hijo siguiente.




Bueno... Si nos concentramos en un nivel se ve que si devuelve todos los
hijos a la vez, pero solo para un nodo a ese nivel, no para todos. Después
para cada hijo sigue descendiendo en el árbol de la misma forma hasta que
termina toda esa rama.
Cuando ha terminado con esa rama la recursión vuelve al nivel en que nos
habíamos concentrado y hace lo mismo para el siguente nodo.

Saludos,
Carlos
Respuesta Responder a este mensaje
#8 alex
10/10/2009 - 03:27 | Informe spam
si, asi es como funciona

gracias!


"Carlos M. Calvelo" wrote in message
news:1vepo0xnq0m00$.1atwx7ci5hw52$
Hola Alejandro,

On Fri, 9 Oct 2009 17:19:37 -0400, alex wrote:

una vez mas gracias por tus comentarios esclarecedores, creo que ya
comprendo, al parecer el inner join no esta trabajando como un inner join
comun porque si fuera asi pues cada iteracion devolveria todos los hijos
de
todos los padres cada vez. Al parecer el inner join devuelve solo uno
hijo a
la vez y sigue por esa rama del arbol hasta que no hay mas, y solo
entonces
pasa al hijo siguiente.




Bueno... Si nos concentramos en un nivel se ve que si devuelve todos los
hijos a la vez, pero solo para un nodo a ese nivel, no para todos. Después
para cada hijo sigue descendiendo en el árbol de la misma forma hasta que
termina toda esa rama.
Cuando ha terminado con esa rama la recursión vuelve al nivel en que nos
habíamos concentrado y hace lo mismo para el siguente nodo.

Saludos,
Carlos
Respuesta Responder a este mensaje
#9 Alejandro Mesa
10/10/2009 - 03:46 | Informe spam
Alex,

segun entiendo van a salir ordenados por LEVEL
automaticamente porque siempre es LEVEL + 1



Creo que estas confundido o que no me comunique correctamente. No esperes
que el resultado este ordenado si no usas "order by" en la sentencia "select"
que lo devuelve.

>> WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)


...
>> SELECT ManagerID, EmployeeID, Title, Level
>> FROM DirectReports




WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
...
SELECT ManagerID, EmployeeID, Title, Level
FROM DirectReports
ORDER BY Level;


AMB




"alex" wrote:

pero cada vez que se ejecuta la CTE recursiva se le asigna LEVEL + 1 a los
siguientes por lo tanto siempre debe ir ascendiendo, y nunca se hace LEVEL -
1, o sea por eso es que no comprendo como es que comienza ascendiendo y
luego desciende. segun entiendo van a salir ordenados por LEVEL
automaticamente porque siempre es LEVEL + 1

"Alejandro Mesa" wrote in message
news:
> Alex,
>
> La unica forma de garantizar un resultado ordenado es usando la clausula
> "order by" en la sentencia "select" que produce el resultado.
>
>> SELECT ManagerID, EmployeeID, Title, Level
>> FROM DirectReports
>
> Si no estas usando esta clausula, como esperas que ocurra el ordenamiento
> de
> el resultado?
>
> SELECT ManagerID, EmployeeID, Title, Level
> FROM DirectReports
> ORDER BY Level;
>
> La sentencia anterior, aunque sea posible que no devuelva lo que tu
> esperas,
> si ordena por la columna [Level]. Para las filas de un mismo nivel, el
> orden
> no ha sido especificado, asi que no podemos esperar un orden especifico
> para
> estas filas dentro del nivel donde se encuentran, al menos que usemos otra
> columna en la clusula "order by".
>
> SELECT ManagerID, EmployeeID, Title, Level
> FROM DirectReports
> ORDER BY Level, EmployeeID;
>
>
> AMB
>
>
> "alex" wrote:
>
>> Hola , tengo una duda con respecto a las CTE's recursivas. El ejemplo que
>> sale en books online al ejecutarlo los resultados comienzan ordenados por
>> la
>> columna LEVEL de menor a mayor 0 1 2 3 4 pero en cierto punto
>> comienza a
>> descender como 0 1 2 3 4 3 3 2, o sea no estan ordenados de menor a mayor
>> todo el tiempo que es como se supone que trabaja haciendo UNION ALL a
>> todos
>> los resultados parciales. Alguien me puede ayudar a comprender esto?
>> El ejemplo de books online (el ultimo WHERE lo elimine para que salgan
>> todos
>> los resultados:
>>
>> USE AdventureWorks;
>> GO
>> WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
>> AS
>> (
>> SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
>> 0 AS Level
>> FROM HumanResources.Employee AS e
>> INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
>> ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL
>> WHERE ManagerID IS NULL
>> UNION ALL
>> SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
>> Level + 1
>> FROM HumanResources.Employee AS e
>> INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
>> ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL
>> INNER JOIN DirectReports AS d
>> ON e.ManagerID = d.EmployeeID
>> )
>> SELECT ManagerID, EmployeeID, Title, Level
>> FROM DirectReports
>>
>>
>>


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida