with sirve que para instruccion cte consulta comando sql-server recursion

sql-server - sirve - with as() sql



¿Es buena la recursión en SQL Server? (8)

¿Estás usando SQL 2005?

De ser así, puede usar Expresiones de tabla comunes para esto. Algo en esta línea:

; with CTE (Some, Columns, ItemId, ParentId) as ( select Some, Columns, ItemId, ParentId from myTable where ItemId = @itemID union all select a.Some, a.Columns, a.ItemId, a.ParentId from myTable as a inner join CTE as b on a.ParentId = b.ItemId where a.ItemId <> b.ItemId ) select * from CTE

Tengo una tabla en el servidor SQL que tiene la estructura de árbol normal de Item_ID, Item_ParentID. Supongamos que quiero iterar y obtener todos los NIÑOS de un Item_ID en particular (en cualquier nivel).

Recursion parece un candidato intuitivo para este problema y puedo escribir una función de SQL Server para hacer esto.

¿Afectará esto el rendimiento si mi tabla tiene muchos registros? ¿Cómo evito la recursión y simplemente consulto la tabla? ¿Alguna sugerencia?


Tal vez un poco más de detalle esté en orden.

Si tiene una relación de detalle maestro como usted lo describe, ¿no obtendrá un JOIN simple lo que necesita?

Como en:

SELECT SOME_FIELDS FROM MASTER_TABLE MT ,CHILD_TABLE CT WHERE CT.PARENT_ID = MT.ITEM_ID


No debería necesitar recursión para niños ; solo está mirando el nivel directamente debajo (es decir, select * from T where ParentId = @parent ) - solo necesita recurrencia para todos los descendientes .

En SQL2005 puede obtener los descendientes con:

with AllDescendants (ItemId, ItemText) as ( select t.ItemId, t.ItemText from [TableName] t where t.ItemId = @ancestorId union select sub.ItemId, sub.ItemText from [TableName] sub inner join [TableName] tree on tree.ItemId = sub.ParentItemId )


No necesita recursividad en absoluto ... Tenga en cuenta que cambié las columnas a ItemID e ItemParentID para facilitar la escritura ...

DECLARE @intLevel INT SET @intLevel = 1

INSERT INTO TempTable(ItemID, ItemParentID, Level) SELECT ItemID, ItemParentID, @intLevel WHERE ItemParentID IS NULL

WHILE @intLevel < @TargetLevel BEGIN SET @intLevel = @intLevel + 1 INSERT INTO TempTable(ItemID, ItemParentID, Level) SELECt ItemID, ItemParentID, @intLevel WHERE ItemParentID IN (SELECT ItemID FROM TempTable WHERE Level = @intLevel-1) -- If no rows are inserted then there are no children IF @@ROWCOUNT = 0 BREAK END

SELECt ItemID FROM TempTable WHERE Level = @TargetLevel


Como respuesta general, es posible hacer algunas cosas bastante sofisticadas en SQL Server que normalmente necesitan recursión, simplemente mediante el uso de un algoritmo iterativo. Logré hacer un analizador XHTML en Transact SQL que funcionó sorprendentemente bien. El pretificador de código que escribí se realizó en un procedimiento almacenado. No es elegante, es más bien como ver búfalos haciendo Ballet. pero funciona .


El problema al que se enfrentará con la recursividad y el rendimiento es cuántas veces tendrá que recurrir para devolver los resultados. Cada llamada recursiva es otra llamada separada que deberá unirse en los resultados totales.

En SQL 2k5 puede usar una expresión de tabla común para manejar esta recursión:

WITH Managers AS ( --initialization SELECT EmployeeID, LastName, ReportsTo FROM Employees WHERE ReportsTo IS NULL UNION ALL --recursive execution SELECT e.employeeID,e.LastName, e.ReportsTo FROM Employees e INNER JOIN Managers m ON e.ReportsTo = m.employeeID ) SELECT * FROM Managers

u otra solución es aplanar la jerarquía en otra tabla

Employee_Managers
ManagerId (PK, FK en la tabla de empleados)
EmployeeId (PK, FK en la tabla de empleados)

Todos los parentescos de relación padre-hijo se almacenarán en esta tabla, por lo que si el Gerente 1 administra al Gerente 2 administra al empleado 3, la tabla se vería así:

ManagerId EmployeeId 1 2 1 3 2 1

Esto permite que la jerarquía sea consultada fácilmente:

select * from employee_managers em inner join employee e on e.employeeid = em.employeeid and em.managerid = 42

Lo cual devolvería a todos los empleados que tienen gerente 42. El aspecto positivo será un mayor rendimiento, pero la desventaja será mantener la jerarquía


Joe Celko tiene un libro (<- enlace a Amazon) específicamente sobre estructuras de árbol en bases de datos SQL. Si bien necesitaría recurrencia para su modelo y definitivamente habría un potencial de problemas de rendimiento allí, existen formas alternativas de modelar una estructura de árbol según lo que implique su problema específico, lo que podría evitar la recursión y brindar un mejor rendimiento.


Con el nuevo MS SQL 2005 puede usar la palabra clave WITH

Mira esta pregunta y particularmente esta respuesta .

Con Oracle, podría usar la palabra clave CONNECT BY para generar consultas jerárquicas ( sintaxis ).

AFAIK con MySQL deberás usar la recursión.

Alternativamente, siempre puedes construir una tabla de caché para tus registros de relaciones padre-> hijo