Gestión de jerarquías en SQL Server(II) : CTE’s
Otra forma de gestionar las jerarquías que proporciona SQL Server son los Common Table Expression (en adelante CTE). Los CTE son expresiones similares a las vistas o a las consultas derivadas (subconsultas) que permiten crear una consulta temporal que puede ser referenciada desde una instrucción DML. Básicamente este tipo de expresiones es muy similar a los miembros calculados que se definen en MDX, claro está, teniendo en cuenta que se trata de un lenguaje relacional. Esto anterior lo digo porque se usa de la siguiente forma
AS ( definicion_contenido_cte )
Instruccion DML
Como entiendo que se ve mucho más claro con un ejemplo, os presento el siguiente:
Lo que se quiere hacer es obtener el máximo en la lista de precios consolidada de productos en stock. Esto se haría en SQL Server 2005 como sigue
INTO #Temp1
FROM Producto p
JOIN SubcategoriaProducto s ON s.IDSubcategoria =
p.IDSubcategoria
WHERE p.IDSubcategoria IS NOT NULL
GROUP BY p.IDSubcategoria, s.Nombre
SELECT IDSubcategoria, Nombre, MAX(SumaPrecios)
FROM #Temp1
GROUP BY IDSubcategoria, Nombre
HAVING MAX(SumaPrecios) = (SELECT MAX(SumaPrecios) FROM #Temp1)
DROP TABLE #Temp1
Como vemos lo que hace es sumar los precios de cada lista agrupados por lista y después obtener el máximo. Con los nuevos CTE esta query quedaría de la siguiente forma:
(
SELECT p.IDSubcategoria, s.Nombre, SUM(Precio) AS SumaPrecios
FROM Producto p
JOIN SubcategoriaProducto s ON s.IDSubcategoria =
p.IDSubcategoria
WHERE p.IDSubcategoriaIS NOT NULL
GROUP BY p.IDSubcategoria, s.Nombre
)
SELECT IDSubcategoria, Nombre, MAX(SumaPrecios)
FROM ListaProductos
GROUP BY IDSubcategoria, Nombre
HAVING MAX(SumaPrecios) = (SELECT MAX(SumaPrecios) FROM ListaProductos)
Este es un ejemplo muy simple de cómo funcionan, aunque a continuación se verá cómo aprovechar más esta nueva característica.
Existen dos tipos de CTE en SQL Server: los recursivos y lo no recursivos. Con los primeros es posible manejar jerarquías, aunque no con la misma potencia que se propone en el post Gestión de jerarquías en SQL Server(I).
Mediante los CTE recursivos es posible crear consultas que devuelvan los datos estructurados jerárquicamente, es decir, podemos construir una jerarquía de elementos idpadre-idelemento-nivel a partir de tablas que no contienen esta información directamente. Como más claro se va a ver es en siguiente ejemplo:
Supongamos que tenemos una tabla con productos que contienen las columnas de IdProducto y otra con la relación con su elemento padre. El nivel es relativamente costoso calcularlo si se realiza de forma tradicional. Por ello, si empleamos una CTE tal como esta
(
SELECT IdProductoPadre, IdProducto, NombreProducto, 0 AS Nivel
FROM Productos
WHERE IdProductoPadre IS NULL
UNION ALL
SELECT p.IdProductoPadre, p.IdProducto, p.NombreProducto, Nivel + 1
FROM Productos p
INNER JOIN JerarquiaProductos j
ON p.IdProductoPadre = j.IdProducto
)
SELECT IdProductoPadre, IdProducto, Nombre, Nivel
FROM JerarquiaProductos
vamos a obtener los siguientes resultados:
| IdProductoPadre | IdProducto | Nombre | Nivel |
| Null | 1 | Coche | 0 |
| 1 | 2 | Motor | 1 |
| 1 | 3 | Chasis | 1 |
| 2 | 4 | Filtro aceite | 2 |
| … |
En el caso de que nuestra jerarquía disponga de multitud de niveles debemos especificar el parámetro MAXRECURSION con el fin de que no colapsemos el sistema. Su valor puede estar entre 1y 32757.
Como vemos, esta característica nos permite representar una jerarquía a partir de orígenes que no contienen esta estructura directamente, junto a operaciones simples sobre los elementos de ella. Pero si queremos un poco más, esta técnica se queda corta.
