Puedes ejecutar cualquier CTE en nuestra consola interactiva: Abrir consola SQL →
CTE en SQL: consultas limpias, reutilizables y profesionales
Las CTE (Common Table Expressions) permiten crear tablas temporales dentro de una consulta. Son ideales para dividir consultas complejas, mejorar la legibilidad y reutilizar resultados intermedios.
Tabla de contenidos
1. ¿Qué es una CTE?
Una CTE es una tabla temporal definida dentro de una consulta mediante la palabra clave WITH.
WITH productos_caros AS (
SELECT * FROM productos WHERE precio > 100
)
SELECT * FROM productos_caros;
2. Sintaxis
WITH nombre_cte AS (
SELECT ...
)
SELECT ...
FROM nombre_cte;
3. CTE múltiples
WITH ventas_totales AS (
SELECT producto_id, SUM(cantidad) AS total
FROM ventas
GROUP BY producto_id
),
productos_info AS (
SELECT id, nombre FROM productos
)
SELECT p.nombre, v.total
FROM productos_info p
JOIN ventas_totales v ON p.id = v.producto_id;
4. CTE con JOIN
WITH clientes_activos AS (
SELECT * FROM clientes WHERE activo = TRUE
)
SELECT c.nombre, p.producto
FROM clientes_activos c
JOIN pedidos p ON c.id = p.cliente_id;
5. CTE vs subconsultas
Las CTE son más legibles, reutilizables y fáciles de depurar que las subconsultas.
WITH promedio AS (
SELECT AVG(precio) AS avg_precio FROM productos
)
SELECT nombre, precio
FROM productos, promedio
WHERE precio > promedio.avg_precio;
6. Ejemplos prácticos
-- Top 3 productos más vendidos
WITH ventas_ordenadas AS (
SELECT producto_id, SUM(cantidad) AS total
FROM ventas
GROUP BY producto_id
ORDER BY total DESC
)
SELECT * FROM ventas_ordenadas LIMIT 3;
-- Clientes con más de 3 pedidos
WITH conteo AS (
SELECT cliente_id, COUNT(*) AS pedidos
FROM pedidos
GROUP BY cliente_id
)
SELECT c.nombre, conteo.pedidos
FROM conteo
JOIN clientes c ON c.id = conteo.cliente_id
WHERE conteo.pedidos > 3;
7. Ejercicios para practicar
- Crea una CTE de productos baratos.
- Crea una CTE con clientes activos.
- Crea dos CTE y únelas con JOIN.
- Reemplaza una subconsulta por una CTE.
- Explica por qué las CTE mejoran la legibilidad.
WITH baratos AS (
SELECT * FROM productos WHERE precio < 20
)
SELECT * FROM baratos;
WITH activos AS (
SELECT * FROM clientes WHERE activo = TRUE
)
SELECT * FROM activos;
WITH c1 AS (SELECT * FROM productos),
c2 AS (SELECT * FROM clientes)
SELECT * FROM c1 CROSS JOIN c2;
WITH promedio AS (
SELECT AVG(precio) AS avg_precio FROM productos
)
SELECT * FROM productos WHERE precio > avg_precio;
-- Las CTE permiten dividir consultas complejas en partes claras.
8. Mini‑proyecto: Ranking de clientes y productos
WITH ventas_por_cliente AS (
SELECT cliente_id, SUM(cantidad) AS total
FROM pedidos
GROUP BY cliente_id
),
ventas_por_producto AS (
SELECT producto_id, SUM(cantidad) AS total
FROM pedidos
GROUP BY producto_id
)
SELECT c.nombre, v.total
FROM ventas_por_cliente v
JOIN clientes c ON c.id = v.cliente_id
ORDER BY v.total DESC;
9. Errores comunes
- Usar CTE innecesarias.
- Crear CTE demasiado grandes.
- No reutilizar CTE cuando es posible.
- Confundir CTE con tablas permanentes.
10. Preguntas frecuentes
¿Las CTE mejoran el rendimiento?
No siempre, pero sí mejoran la legibilidad.
¿Puedo usar varias CTE?
Sí, tantas como necesites.