Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 1 de 425/57 en el curso~12 min
Lecciones del módulo (1/4)

CTE: consultas de múltiples pasos con WITH

Las consultas reales tienden a crecer: tres JOIN, un GROUP BY, una subconsulta, otra subconsulta… y se vuelven ilegibles. CTE ("Tabla Común Expressions", la cláusula WITH) le permiten dar un nombre a un paso intermedio y utilizarlo como si fuera una tabla en la consulta principal.

Sintaxis básica

SQL
WITH nome_cte AS (
  SELECT-- query interna
)
SELECT-- query principale, usa nome_cte come fosse una tabella
FROM   nome_cte;

Un CTE es válido sólo para la consulta que le sigue: no sobrevive la ejecución.

Ejemplo

Encuentre los 3 clientes que han gastado más (suma sobre pedidos entregados):

SQL
WITH total_spent AS (
  SELECT o.customer_id,
         SUM(oi.quantity * oi.unit_price) AS total
  FROM   orders      o
  JOIN   order_items oi ON oi.order_id = o.id
  WHERE  o.status = 'delivered'
  GROUP BY o.customer_id
)
SELECT c.email,
       s.total
FROM   total_spent s
JOIN   customers c ON c.id = s.customer_id
ORDER BY s.total DESC
LIMIT  3;

Leer en inglés: "primero calcule el gasto por cliente; luego únase a clientes y ocupar el top 3". Sin un CTE necesitarías un en línea subconsulta en FROM (legal, pero más ruidosa).

Múltiples CTE en cascada

Puede definir múltiples CTE separados por comas, y cada uno puede hacer referencia a los anteriores:

SQL
WITH total_spent AS (
  SELECT customer_id, SUM(quantity * unit_price) AS total
  FROM   order_items oi
  JOIN   orders      o ON oi.order_id = o.id
  WHERE  o.status = 'delivered'
  GROUP BY customer_id
),
average AS (
  SELECT AVG(total) AS total_average
  FROM   total_spent
)
SELECT c.email, s.total
FROM   total_spent s
JOIN   customers c ON c.id = s.customer_id
CROSS JOIN average
WHERE  s.total > average.total_average
ORDER BY s.total DESC;

CROSS JOIN average porque average siempre tiene una sola fila: la El producto cartesiano simplemente agrega total_average a cada fila del resultado.

CTE vs subconsulta: cuándo usar cuál

Los CTE brillan cuando:

  • la misma subconsulta se utiliza dos o más veces en la consulta principal;
  • desea que la estructura sea explícita en pasos con nombre (autodocumentados);
  • son el requisito previo para CTE recursivos (WITH RECURSIVE, la siguiente lección de este módulo).

Una subconsulta en línea es más concisa para un paso que se usa solo una vez.

Pruébalo

Ejercicio#sql.m7.l1.e1
Intentos: 0Cargando...

Utilice un CTE denominado 'total_spent' que calcule, para cada cliente, el gasto total (SUM(cantidad * precio_unitario)) en los pedidos entregados. Luego, en la consulta principal, muestre el correo electrónico y el total de los 3 mayores gastadores. Ordenar por total descendente, límite a 3.

Cargando editor...
Mostrar pista

Dentro del CTE suma cantidad * precio_unitario. En la consulta principal ÚNETE a los clientes con id.

Solución disponible después de 3 intentos

Ejercicio de revisión

Ejercicio#sql.m7.l1.e2
Intentos: 0Cargando...

Mismo CTE 'total_gastado' que el ejercicio anterior. En la consulta principal, muestre el correo electrónico y el total de los clientes cuyo gasto está por encima del gasto promedio (en todos los clientes con al menos un pedido entregado). Ordenar por total descendente.

Cargando editor...
Mostrar pista

Subconsulta escalar en DONDE: SELECCIONE AVG(total) FROM total_spent.

Solución disponible después de 3 intentos