Reducir el trabajo: agregar antes de unir
IntermedioUna consulta rinde mejor cuando cada paso recibe la menor cantidad de filas y columnas posible. Tres hábitos: agregar la tabla grande antes de unirla con la chica, seleccionar solo las columnas que usas en lugar de SELECT *, y usar EXISTS cuando solo te importa si hay al menos una fila relacionada, en lugar de un join seguido de DISTINCT.
Sintaxis
WITH resumen AS (
SELECT clave, count(*) AS n, sum(valor) AS total
FROM tabla_grande
WHERE filtro
GROUP BY clave
)
SELECT d.nombre, r.n, r.total
FROM resumen AS r
INNER JOIN dimension AS d ON d.id = r.clave;Ejemplo
WITH ventas_agosto AS (
SELECT restaurant_id, count(*) AS pedidos, sum(total) AS facturado
FROM orders
WHERE status = 'delivered'
AND placed_at >= '2025-08-01'
AND placed_at < '2025-09-01'
AND restaurant_id IN (SELECT id FROM restaurants WHERE city_id = 6)
GROUP BY restaurant_id
)
SELECT r.id, r.name AS restaurante, v.pedidos, v.facturado
FROM ventas_agosto AS v
INNER JOIN restaurants AS r ON r.id = v.restaurant_id
ORDER BY v.facturado DESC, r.id
LIMIT 5;Resultado
| id | restaurante | pedidos | facturado |
|---|---|---|---|
| 200 | El Rincón Morales 200 | 5 | 237756.50 |
| 87 | Doña Gutiérrez 87 | 3 | 196308.00 |
| 257 | Casa Mamani 257 | 4 | 181235.30 |
| 352 | Sabor Mendoza 352 | 5 | 178695.00 |
| 99 | Casa Silva 99 | 4 | 173337.00 |
Cómo leerlo
Son los cinco restaurantes de Santiago (city_id = 6) que más facturaron en agosto de 2025, en pesos chilenos. La CTE filtra primero los pedidos (entregados, de agosto, de restaurantes de Santiago) y los reduce a una fila por restaurante; el join con restaurants solo agrega el nombre sobre ese resumen. El resultado es el mismo que con el join primero; lo que baja es la cantidad de filas en cada paso intermedio.
Error común
Así no
SELECT DISTINCT r.*
FROM restaurants AS r
INNER JOIN orders AS o ON o.restaurant_id = r.id
WHERE r.city_id = 6
AND o.placed_at >= '2025-08-01'
AND o.placed_at < '2025-09-01';Unir con la tabla de pedidos y usar DISTINCT para preguntar qué restaurantes tuvieron actividad. El join repite cada restaurante una vez por pedido y después el DISTINCT tiene que ordenar o agrupar todas esas filas para eliminar las repetidas. WHERE EXISTS (SELECT 1 FROM orders AS o WHERE o.restaurant_id = r.id AND …) responde lo mismo y el motor puede dejar de buscar en cuanto encuentra el primer pedido.
En otros motores: BigQuery, Snowflake
BigQuerySnowflake
Guardan los datos por columna, así que
SELECT *lee todas las columnas de la tabla. En BigQuery, con facturación por datos procesados, eso se traduce directamente en costo, y en general agregarLIMITno reduce lo que se lee.
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.