Contenido de esta guía
Qué significa
Una CTE —common table expression o expresión de tabla común— es un resultado auxiliar con nombre definido mediante WITH. Existe solo durante la sentencia que la utiliza y puede leerse como una etapa intermedia de la consulta.
- Nombra un paso con una responsabilidad clara.
- Separa la obtención de datos de su presentación o agregación.
- No crea una tabla ni una vista permanente.
Cuándo ayuda una CTE
Una CTE resulta útil cuando una subconsulta anidada dificulta seguir el razonamiento, cuando varias partes de una sentencia necesitan referirse al mismo conjunto o cuando quieres explicar una consulta por etapas. No es una garantía de rendimiento: el optimizador puede integrar o materializar el resultado según el motor y la consulta.
Buen nombre: describe qué filas contiene la CTE, no cómo se construye. pedidos_enviados comunica más que datos1.
Sintaxis básica
WITH nombre_cte AS (
SELECT ...
)
SELECT ...
FROM nombre_cte;Ejemplo guiado con pedidos reales
Primero aislamos los pedidos enviados. Después calculamos el total enviado por cliente:
WITH pedidos_enviados AS (
SELECT cliente_id, total
FROM pedidos
WHERE estado = 'enviado'
)
SELECT cliente_id,
ROUND(SUM(total), 2) AS total_enviado
FROM pedidos_enviados
GROUP BY cliente_id
ORDER BY cliente_id;| cliente_id | total_enviado |
|---|---|
| 1 | 128.40 |
| 3 | 215.90 |
| 5 | 1112.00 |
| 7 | 148.90 |
| 9 | 61.50 |
| 10 | 54.00 |
| 11 | 98.00 |
Cómo se divide el razonamiento
- La CTE conserva únicamente filas con estado
enviado. - La consulta exterior agrupa ese conjunto por
cliente_id. SUM(total)calcula el importe de cada cliente.ROUNDpresenta dos decimales yORDER BYfija un orden legible.
Error frecuente
Intentar usar la CTE en una sentencia posterior
WITH enviados AS (
SELECT * FROM pedidos WHERE estado = 'enviado'
);
SELECT * FROM enviados;La definición WITH debe estar unida a la sentencia que consume la CTE. El punto y coma termina la sentencia antes del SELECT. Para reutilizar un resultado en consultas futuras, estudia una vista o una tabla temporal.
Comprueba lo aprendido
Separa el filtro de la presentación
Crea una CTE llamada productos_disponibles con nombre y precio de los productos cuyo stock sea mayor que cero. Después consulta la CTE y ordena por precio y nombre.
WITH productos_disponibles AS (...).WHERE stock > 0.ORDER BY.Solución razonada
WITH productos_disponibles AS (
SELECT nombre, precio
FROM productos
WHERE stock > 0
)
SELECT nombre, precio
FROM productos_disponibles
ORDER BY precio, nombre;| nombre | precio |
|---|---|
| Cable USB-C | 12.00 |
| Ratón | 24.90 |
| Teclado | 49.50 |
| Auriculares | 69.90 |
La CTE resuelve qué productos están disponibles; la consulta exterior decide cómo mostrarlos. El producto “Portátil Pro” no aparece porque su stock es cero.
Compatibilidad, recursión y rendimiento
Las CTE ordinarias están disponibles en las versiones actuales de PostgreSQL, SQLite, MySQL y SQL Server, aunque las versiones antiguas pueden no soportarlas. Las CTE recursivas añaden reglas propias y deben estudiarse por separado. PostgreSQL, SQLite y MySQL permiten que el optimizador decida entre integrar o materializar determinados resultados; por eso WITH mejora primero la claridad, no necesariamente la velocidad. En SQL Server, una sentencia anterior al WITH debe terminar correctamente, y es habitual escribir ;WITH cuando existe riesgo de omitir ese separador.
Qué debes recordar
- Una CTE es un resultado con nombre y alcance de una sola sentencia.
- Ayuda a dividir una consulta en pasos comprensibles.
- No crea una vista permanente ni garantiza materialización.
- Las CTE recursivas y el rendimiento requieren comprobaciones específicas.
Conceptos relacionados
Fuentes técnicas consultadas
El alcance de una CTE, sus formas ordinarias y las decisiones de materialización se contrastaron con estas fuentes oficiales.