Published on

April 15, 2023

Implementando consultas recursivas en SQL Server utilizando Expresiones de Tabla Comunes (CTE)

Problema: Necesitamos una mejor manera de implementar consultas recursivas en SQL Server.

Solución: La Expresión de Tabla Común (CTE) proporciona una solución para implementar consultas recursivas en SQL Server. CTE se puede pensar como un conjunto de resultados temporales que se define dentro del ámbito de ejecución de una única instrucción SELECT, INSERT, UPDATE, DELETE o CREATE VIEW. Es una versión mejorada de las tablas derivadas que se asemeja estrechamente a un tipo de vista no persistente. Las CTE se pueden utilizar de muchas de las mismas formas que las tablas derivadas y también pueden contener referencias a sí mismas, lo que facilita la escritura de consultas complejas.

Ventajas de utilizar CTE:

  • Las consultas con definiciones de tablas derivadas se vuelven más simples y legibles.
  • Las CTE reducen significativamente la cantidad de código requerido para una consulta que recorre jerarquías recursivas.

Para crear una CTE en SQL Server, puedes utilizar la siguiente sintaxis:

WITH cte_alias (column_aliases)
AS
(
cte_query_definition -- inicialización
UNION ALL
cte_query_definition2 -- ejecución recursiva
)
SELECT * FROM cte_alias

Aquí tienes un ejemplo de una CTE que utiliza recursión:

WITH Managers AS
(
-- inicialización
SELECT EmployeeID, LastName, ReportsTo
FROM Employees
WHERE ReportsTo IS NULL
UNION ALL
-- ejecución recursiva
SELECT e.EmployeeID, e.LastName, e.ReportsTo
FROM Employees e
INNER JOIN Managers m ON e.ReportsTo = m.EmployeeID
)
SELECT * FROM Managers

En este ejemplo, la CTE “Managers” se utiliza para averiguar quién reporta a quién en la tabla Employees de la base de datos Northwind. La consulta de inicialización devuelve el resultado base, que es el nivel más alto en la jerarquía (identificado por el valor ReportsTo NULL). La consulta de ejecución recursiva se une a la consulta de inicialización utilizando la palabra clave UNION ALL, y el conjunto de resultados se basa en los subordinados directos devueltos por la consulta de inicialización. La recursión ocurre porque la consulta hace referencia a la CTE misma basada en el Empleado en la CTE Managers como entrada.

También puedes utilizar la sugerencia de consulta MAXRECURSION para detener una instrucción después de un número definido de bucles. Esto puede evitar que una CTE entre en un bucle infinito en una instrucción mal codificada. Para utilizar la sugerencia MAXRECURSION, puedes incluirla en la consulta SELECT que hace referencia a la CTE. Por ejemplo:

SELECT * FROM Managers OPTION (MAXRECURSION 4)

Si quieres lograr un resultado similar sin utilizar una CTE, tendrías que escribir una consulta más compleja utilizando variables de tabla y bucles. Aquí tienes un ejemplo:

DECLARE @rowsAdded INT

-- variable de tabla para almacenar los resultados acumulados
DECLARE @managers TABLE
(
EmpID INT,
MgrID INT,
LastName nvarchar(20),
processed INT DEFAULT(0)
)

INSERT @managers
SELECT EmployeeID, ReportsTo, LastName, 0
FROM Employees
WHERE ReportsTo IS NULL

SET @rowsAdded = @@ROWCOUNT

-- hacer esto mientras se agreguen nuevos empleados en la iteración anterior
WHILE @rowsAdded > 0
BEGIN
-- marcar registros de empleados que se encontrarán en esta iteración con processed=1
UPDATE @managers SET processed = 1 WHERE processed = 0

-- insertar empleados que reportan a empleados aún no procesados
INSERT @managers
SELECT EmployeeID, ReportsTo, e.LastName, 0
FROM Employees e
INNER JOIN @managers r ON e.ReportsTo = r.EmpID
WHERE ReportsTo <> EmployeeID AND r.processed = 1

SET @rowsAdded = @@ROWCOUNT

-- marcar registros de empleados encontrados en esta iteración como procesados
UPDATE @managers SET processed = 2 WHERE processed = 1
END

SELECT EmpID as EmployeeID, LastName, MgrID as ReportsTo FROM @managers

Sin embargo, utilizar una CTE proporciona una forma más legible y eficiente de lograr el mismo resultado.

En conclusión, las Expresiones de Tabla Comunes (CTEs) son una característica poderosa en SQL Server que permiten la implementación de consultas recursivas. Proporcionan una forma más simple y legible de trabajar con tablas derivadas y reducen significativamente la cantidad de código requerido para consultas que recorren jerarquías recursivas.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.