Consultas · guía rápida

WITH y CTE

Nombra resultados intermedios para leer una consulta por etapas, sin confundir una CTE con una vista o una tabla permanente.

Lectura: 6–8 minEjemplo paso a pasoPráctica con pistas
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

Estructura
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:

SQL
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;
Resultado esperado
cliente_idtotal_enviado
1128.40
3215.90
51112.00
7148.90
961.50
1054.00
1198.00

Cómo se divide el razonamiento

  1. La CTE conserva únicamente filas con estado enviado.
  2. La consulta exterior agrupa ese conjunto por cliente_id.
  3. SUM(total) calcula el importe de cada cliente.
  4. ROUND presenta dos decimales y ORDER BY fija un orden legible.

Error frecuente

Intentar usar la CTE en una sentencia posterior

Consulta problemática
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

Básica · apoyo graduado

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.

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.