Kodokon kodokon.com

HAVING y agregaciones avanzadas

Filtra después de la agregación con HAVING y pivota tus datos con CASE WHEN dentro de funciones de agregación.

8 min · 3 preguntas

Abrir esta lección en Kodokon

Ya conoces GROUP BY. Este módulo aborda lo que separa una consulta correcta de una profesional: el filtrado posterior a la agregación, las agregaciones condicionales y un dominio sólido del orden de evaluación. Para practicar, abre sqliteonline.com (motor SQLite) o inicia sqlite3 en una terminal: cada lección proporciona las instrucciones CREATE TABLE e INSERT que necesitas. Copia este conjunto de datos antes de ejecutar los ejemplos.

SQL
CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer TEXT NOT NULL,
  category TEXT NOT NULL,
  amount REAL NOT NULL,
  status TEXT NOT NULL
);

INSERT INTO orders (customer, category, amount, status)
VALUES
  ('alice', 'books', 42.0, 'paid'),
  ('alice', 'games', 55.0, 'paid'),
  ('alice', 'books', 18.5, 'refunded'),
  ('bruno', 'games', 70.0, 'paid'),
  ('bruno', 'books', 12.0, 'paid'),
  ('chloe', 'games', 95.0, 'paid'),
  ('chloe', 'books', 30.0, 'paid'),
  ('david', 'books', 8.0, 'refunded');
Conjunto de datos de esta lección, ejecútalo primero.

El orden lógico de evaluación es la clave: FROMWHEREGROUP BYHAVINGSELECTORDER BY. WHERE filtra las filas antes de agrupar; HAVING filtra los grupos después de calcular las agregaciones. Por eso WHERE SUM(amount) > 90 es ilegal: en la etapa WHERE, todavía no existe ninguna suma. Aquí conservamos solo los clientes cuyo total pagado supera 90 (se espera: alice y chloe).

SQL
SELECT customer,
       COUNT(*) AS nb_orders,
       SUM(amount) AS total
FROM orders
WHERE status = 'paid'
GROUP BY customer
HAVING SUM(amount) > 90;
WHERE elimina filas, HAVING elimina grupos.

El segundo patrón imprescindible es la agregación condicional. Al introducir un CASE WHEN dentro de SUM o COUNT, calculas varias métricas en una sola pasada por la tabla, donde un principiante ejecutaría tres consultas separadas. Esta es la técnica estándar para pivotar filas en columnas.

SQL
SELECT customer,
  SUM(CASE WHEN category = 'books'
      THEN amount ELSE 0 END) AS books_total,
  SUM(CASE WHEN category = 'games'
      THEN amount ELSE 0 END) AS games_total
FROM orders
WHERE status = 'paid'
GROUP BY customer;
Pivotar filas → columnas en una sola lectura.

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿En qué orden lógico evalúa el motor estas cláusulas?
    • WHERE → GROUP BY → HAVING
    • HAVING → WHERE → GROUP BY
    • GROUP BY → HAVING → WHERE
  2. ¿Qué condición debería quedarse en WHERE en lugar de HAVING?
    • SUM(amount) > 100
    • status = 'paid'
    • COUNT(*) >= 2
  3. ¿Qué calcula SUM(CASE WHEN category = 'books' THEN amount ELSE 0 END)?
    • El total de todos los pedidos
    • El total de solo las filas de la categoría 'books'
    • El número de filas de la categoría 'books'
    • El total de las filas fuera de 'books'