Kenneth Angulo L
Esta grafica permite entender lo que explica el profesor. Es el orden en que se ejecutan los comandos en SQL:
Miguel Peñaranda
Excelente aporte
Saber cuándo filtrar filas y cuándo filtrar grupos es una de las diferencias más importantes a la hora de escribir consultas SQL eficientes. HAVING es la cláusula que permite aplicar condiciones sobre los resultados de una agrupación, y confundirla con WHERE no solo produce resultados incorrectos, sino que puede afectar significativamente el rendimiento en tablas grandes.
¿Cuál es la diferencia entre WHERE y HAVING en SQL?
Aunque ambas cláusulas sirven para filtrar, actúan en momentos distintos del proceso de ejecución de una query [0:15]:
Son dos filtros que operan en etapas diferentes, y la gran ventaja es que podemos usar ambos dentro de la misma consulta. Primero WHERE reduce las filas que entran a la agrupación, y luego HAVING descarta los grupos que no cumplen la condición deseada.
¿Cómo funciona HAVING con una agrupación simple?
Para ilustrarlo, se parte de la tabla productos en la base de datos Tienda Latam. El objetivo es encontrar las categorías con más de cinco productos [1:22].
Primero se ejecuta la agrupación sin HAVING:
sql SELECT categoriaID, COUNT(*) AS cantidad_productos FROM productos GROUP BY categoriaID;
Este resultado devuelve ocho filas mostrando cuántos productos tiene cada categoría: cinco, cuatro, seis, tres, ocho, entre otros valores. Hasta aquí solo hay una función de agregación (COUNT) combinada con GROUP BY.
Ahora se aplica el filtro posterior con HAVING [2:25]:
sql SELECT categoriaID, COUNT() AS cantidad_productos FROM productos GROUP BY categoriaID HAVING COUNT() > 5;
El resultado se reduce a solo dos categorías (categoría 1 y categoría 2), que son las únicas con más de cinco elementos. Si se necesita incluir las que tienen exactamente cinco, basta con cambiar el operador a >=:
sql HAVING COUNT(*) >= 5;
Con ese ajuste, el resultado pasa a cuatro categorías. El operador mayor estricto (>) excluye el valor indicado, mientras que mayor o igual (>=) lo incluye.
¿Cómo combinar WHERE y HAVING en una misma consulta?
El verdadero poder aparece cuando se necesitan ambos filtros. El ejemplo trabaja con la tabla pedidos y busca los clientes que realizaron más de tres pedidos durante el año 2024 [3:20].
La construcción paso a paso es la siguiente:
sql SELECT clienteID, COUNT() AS pedidos_2024 FROM pedidos WHERE EXTRACT(YEAR FROM fecha_pedido) = 2024 GROUP BY clienteID HAVING COUNT() > 3 ORDER BY pedidos_2024 DESC;
¿Qué hace cada parte de la query?
EXTRACT: aplica una función de tiempo que extrae el año de la columna fecha_pedido y filtra solo las filas del año 2024. Este es el primer filtro, que actúa antes de la agrupación [3:50].clienteID.Al ejecutar la consulta completa, el resultado muestra únicamente al cliente 100 y al cliente 81, que son los únicos que superaron tres pedidos en 2024.
¿Cuál es el orden correcto de las cláusulas en SQL?
La secuencia lógica que se debe respetar es:
SELECT con las columnas y funciones de agregación.FROM indicando la tabla de origen.WHERE para filtrar filas individuales.GROUP BY para agrupar lo que no es agregación.HAVING para filtrar los grupos resultantes.ORDER BY para ordenar la salida final.Respetar este orden garantiza que cada filtro actúe en el momento correcto y que los resultados sean precisos.
Pon a prueba lo aprendido con estos tres ejercicios sobre Tienda Latam: categorías con más de diez productos, países con más de cien clientes y clientes con más de tres pedidos. Comparte tus resultados en los comentarios.
Kenneth Angulo L
Esta grafica permite entender lo que explica el profesor. Es el orden en que se ejecutan los comandos en SQL:
Miguel Peñaranda
Excelente aporte
David Josué Camperos Hernández
Mi solución:
-- Categorias con mas de 5 productos SELECT categoria_id, COUNT(*) AS cantidad_productos FROM productos GROUP BY categoria_id HAVING COUNT(*) >= 5 ORDER BY categoria_id ASC; -- Paises con mas de 10 clientes SELECT pais_id, COUNT(pais_id) AS cantidad_clientes FROM clientes GROUP BY pais_id HAVING COUNT(*) >= 10 ORDER BY cantidad_clientes DESC; -- Clientes con mas de 3 pedidos SELECT cliente_id, COUNT(*) AS cantidad_pedidos FROM pedidos GROUP BY cliente_id HAVING COUNT(*) >= 3 ORDER BY cantidad_pedidos DESC;
Valeria Velasquez
Modifiqué los criterios de filtrado originales de las consignas, debido a que los datos disponibles en la base no alcanzan esos valores.
-- Categorias con más de 4 productos SELECT categoria_id, COUNT (*) AS productos_cat FROM productos GROUP BY categoria_id HAVING COUNT (*) > 4 ORDER BY productos_cat DESC; -- Paises con más e igual a 10 clientes SELECT pais_id, COUNT(*) AS clientes_pais FROM clientes GROUP BY pais_id HAVING COUNT(*) >= 10 ORDER BY clientes_pais DESC; --Clientes con más de 3 pedidos SELECT cliente_id, COUNT(*) AS clientes_pedidos FROM pedidos GROUP BY cliente_id HAVING COUNT(*) > 3 ORDER BY clientes_pedidos DESC;
Juan Quetglas Escarate
-- categorias con mas de 3 productos
SELECT
categoriaid,
COUNT(*) AS cantidad_productos
FROM productos
GROUP BY categoriaid
HAVING COUNT(*) > 3
order by categoriaid desc;
-- paises con más de 10 clientes
select
clientes.paisid,
paises.nombrepais,
count(*) as num_clientes
from clientes
join paises on clientes.paisid = paises.paisid
group by clientes.paisid, paises.nombrepais
having count(*) > 10;
-- clientes con mas de tres pedidos
select
clienteid,
pedidoid,
count(*) as num_pedidos
from pedidos
group by clienteid, pedidoid
having count(*) > 3
order by num_pedidos asc;
Cristian camilo Orjuela Rodríguez
--PRIMER EJERCICIO SELECT categoriaid, COUNT(productoid) AS numero_productos FROM productos GROUP BY categoriaid HAVING COUNT(categoriaid)>=5 ORDER BY numero_productos; -- SEGUNDO EJERCICIO SELECT paisid, COUNT(*) AS numero_clientes FROM clientes GROUP BY paisid HAVING COUNT(*)>=7 ORDER BY numero_clientes ACDS; -- TERCER EJERCICIO SELECT clienteid, COUNT(pedidoid) AS numero_pedidos FROM pedidos GROUP BY clienteid HAVING COUNT(pedidoid)>=3 ORDER BY numero_pedidos DESC
Jubidza Johanna Flores Gutierrez
Mi resolucion
--Categoria con más de 10 productos--
SELECT
categoriaid,
COUNT(*) AS categorias_productos
FROM productos
GROUP BY categoriaid
HAVING COUNT(*) > 10
ORDER BY categoriaid;
--Paises con más de 100 clientes--
SELECT
paisid,
COUNT(*) AS cantidad_clientes
FROM clientes
GROUP BY paisid
HAVING COUNT(*) > 100
ORDER BY paisid;
--Clientes que realizaron más de 3 pedidos--
SELECT
clienteid,
COUNT(*) AS cantidad_pedidos
FROM pedidos
GROUP BY clienteid
HAVING COUNT(*) > 3
ORDER BY clienteid;
Bladimir Balbin Vasquez
Aqui los 3 ejercicios
--ejercicio categorías con mas de diez productos
SELECT p.categoriaid, c.nombrecategoria, count(*) AS total_productos
FROM productos p
LEFT JOIN categorias c ON c.categoriaid = p.categoriaid
GROUP BY p.categoriaid, c.nombrecategoria
HAVING count(*) >= 10
ORDER BY count(*) DESC;
--paises con mas de cien clientes
SELECT c.paisid, p.nombrepais, count(*) total_clientes_pais
FROM clientes c
LEFT JOIN paises p ON p.paisid = c.paisid
GROUP BY c.paisid, p.nombrepais
HAVING count(*) > 100;
--clientes con mas de 3 pedidos
SELECT p.clienteid, c.nombre || ' ' || c.apellido, count(*) AS total_pedidos
FROM pedidos p
LEFT JOIN clientes c ON c.clienteid = p.clienteid
GROUP BY p.clienteid, c.nombre, c.apellido
HAVING count(*) > 3
Diego Alejandro Gil Rave
Mi solución
-- categorías con más de 3 productos SELECT categoriaid, COUNT(productoid) AS numero_productos FROM productos GROUP BY categoriaid HAVING COUNT(*)>=3 ORDER BY numero_productos LIMIT 5; -- países con más de siete clientes SELECT paisid, COUNT(*) AS numero_clientes FROM clientes GROUP BY paisid HAVING COUNT(*)>7 ORDER BY numero_clientes DESC; -- clientes con más de tres pedidos SELECT clienteid, COUNT(pedidoid) AS numero_pedidos FROM pedidos GROUP BY clienteid HAVING COUNT(pedidoid)>3 ORDER BY numero_pedidos DESC LIMIT 10;
Diego Mauricio Zuluaga Rodríguez
Diego Mauricio Zuluaga Rodríguez
Diego Mauricio Zuluaga Rodríguez
Comparto el código de la clase:
-- ============================================================ -- C22 · HAVING: filtrar grupos -- Curso: SQL con PostgreSQL — TiendaLatam -- ============================================================ -- HAVING básico: categorías con más de 5 productos SELECT categoria_id, COUNT(*) AS cantidad_productos FROM productos GROUP BY categoria_id -- Sin HAVING trae 8 resultados con la cantidad_productos por ID. -- Usamos HAVING para filtrar el anterior resultado y solo -- obtener los id con más de 5 productos. HAVING COUNT(*) > 5; -- Categorías con 5 o más productos. SELECT categoria_id, COUNT(*) AS cantidad_productos FROM productos GROUP BY categoria_id HAVING COUNT(*) >= 5; -- WHERE + HAVING: solo pedidos de 2024, grupos con más de 3 pedidos SELECT cliente_id, COUNT(*) AS pedidos_2024 FROM pedidos WHERE EXTRACT(YEAR FROM fecha_pedido) = 2024 GROUP BY cliente_id HAVING COUNT(*) > 3 ORDER BY pedidos_2024 DESC;
Javier Cano
Jhon Alexander Mosquera Vanegas
La diferencia entre WHERE y HAVING es de pregunta más que de sintaxis. En la clase, WHERE deja primero solo los pedidos de 2024 y después HAVING conserva a los clientes con más de tres pedidos dentro de ese conjunto. Si se quitara el WHERE, el mismo umbral contaría pedidos de todos los años y la lista de clientes sería otra. Por eso, al revisar un reporte ajeno, conviene preguntar sobre qué conjunto se calculó cada grupo antes de comparar cifras, porque dos informes con el mismo umbral pueden estar midiendo universos distintos.
Juan Sebastián Martínez Medina
Consulta 1:
SELECT c.nombre_categoria, COUNT(*) AS cantidad_productos
FROM productos AS p JOIN categorias c ON c.categoria_id = p.categoria_id
GROUP BY c.nombre_categoria
HAVING COUNT(*) > 10;
Consulta 2:
SELECT p.nombre_pais, COUNT(*) AS cantidad_clientes
FROM clientes AS c JOIN paises AS p ON c.pais_id = p.pais_id
GROUP BY p.nombre_pais
HAVING COUNT(*) > 100;
Consulta 3:
SELECT c.nombre_cliente, COUNT(*) AS cantidad_pedidos
FROM pedidos AS p JOIN clientes AS c ON p.cliente_id = c.cliente_id
GROUP BY c.nombre_cliente
HAVING COUNT(*) > 3;
Anette Iniesta Garcia
Ejercicio 1 (se filtra con el mayor número que tiene la tabla, ya que no hay mas de 8)
Ejercicio 2 (se filtra con el mayor número que tiene la tabla, ya que no hay mas de 10):
Ejercicio 3:
Janeth Griselda Bravo Morales
-- Reto 1: Categorías con más de 5 productos (No hay de 10)
SELECT
categoria_id,
COUNT(*) AS total_productos
FROM productos
GROUP BY categoria_id
HAVING COUNT(*) > 5
ORDER BY total_productos DESC;
-- Reto 2 países con más de ocho clientes y con más de dos pedidos
SELECT
c.cliente_id,
c.nombre,
c.apellido,
COUNT(*) AS total_pedidos
FROM pedidos AS p
JOIN clientes AS c ON p.cliente_id = c.cliente_id
GROUP BY c.cliente_id, c.nombre, c.apellido
HAVING COUNT(*) > 2
ORDER BY total_pedidos DESC;
-- Reto 3: Clientes con más de 3 pedidos (con nombre completo)
SELECT
c.cliente_id,
c.nombre,
c.apellido,
COUNT(*) AS total_pedidos
FROM pedidos AS p
JOIN clientes AS c ON p.cliente_id = c.cliente_id
GROUP BY c.cliente_id, c.nombre, c.apellido
HAVING COUNT(*) > 3
ORDER BY total_pedidos DESC;
Sebastian Sanchez Jaramillo
Me tocó realizar unos cambios en los valores, ya que la fuente de datos no contiene esas cantidades.
Daniel Urango
--categorias con más de 10 productos
SELECT
categoria_id,
COUNT(*) AS total_productos
FROM productos
GROUP BY categoria_id
HAVING COUNT(*) > 10;
--paises con más de 6 clientes:
SELECT
pais_id,
COUNT(*) AS total_clientes
FROM clientes
GROUP BY pais_id
HAVING COUNT(*) > 6;
--clientes que realizaron mas de 3 pedidos
SELECT
cliente_id,
COUNT(*) AS total_pedidos
FROM pedidos
GROUP BY cliente_id
HAVING COUNT(*) > 3;
Comparto los otros ejercicios que estaban en el archivo de Recursos, no realizados en el video de la clase:
-- OTROS EJERCICIOS -- HAVING básico: categorías (con nombre) con más de 5 productos SELECT c.nombre_categoria AS categoria, COUNT(*) AS cantidad_productos FROM productos p JOIN categorias c ON p.categoria_id = c.categoria_id GROUP BY c.categoria_id, c.nombre_categoria HAVING COUNT(*) > 5 ORDER BY cantidad_productos DESC;
-- HAVING con SUM: países con más de $50,000 en ventas SELECT pa.nombre_pais AS pais, SUM(dp.cantidad * dp.precio_unitario) AS total_ventas FROM pedidos p JOIN sucursales s ON p.sucursal_id = s.sucursal_id JOIN paises pa ON s.pais_id = pa.pais_id JOIN detalles_pedidos dp ON p.pedido_id = dp.pedido_id GROUP BY pa.pais_id, pa.nombre_pais HAVING SUM(dp.cantidad * dp.precio_unitario) > 50000 ORDER BY total_ventas DESC;
-- HAVING con AVG: clientes con ticket promedio alto (>1000) SELECT c.nombre_cliente AS cliente, COUNT(p.pedido_id) AS pedidos, AVG(dp.cantidad * dp.precio_unitario) AS ticket_promedio FROM clientes c JOIN pedidos p ON c.cliente_id = p.cliente_id JOIN detalles_pedidos dp ON p.pedido_id = dp.pedido_id GROUP BY c.cliente_id, c.nombre_cliente HAVING AVG(dp.cantidad * dp.precio_unitario) > 1000 ORDER BY ticket_promedio DESC;
-- Nombre de categorías con más de 3 productos SELECT c.nombre_categoria AS categoria, COUNT(*) AS total_productos FROM productos p JOIN categorias c ON p.categoria_id = c.categoria_id GROUP BY c.categoria_id, c.nombre_categoria HAVING COUNT(*) > 3 ORDER BY total_productos DESC;
Comparto el RETO con resultados:
-- RETO -- 1. Categorías con más de 5 productos. SELECT categoria_id, COUNT(*) as cantidad_productos FROM productos GROUP BY categoria_id HAVING COUNT(*) > 5 ORDER BY cantidad_productos; -- Resultado: las categorías 1 y 2 tienen más de 5 productos. -- El máximo de productos es 8.
-- 2. Países con más de 10 clientes. SELECT pais_id, COUNT(*) as total_clientes FROM clientes GROUP BY pais_id HAVING COUNT(*) > 10 ORDER BY total_clientes DESC; -- Resultado: los países 1 y 8 tienen el máximo de 11 clientes.
-- 3. Clientes con más de tres pedidos. SELECT cliente_id, COUNT(*) AS pedidos_por_cliente FROM pedidos GROUP BY cliente_id HAVING COUNT(*) > 3 ORDER BY pedidos_por_cliente DESC; -- Resultado: 15 clientes tienen más de 3 pedidos. -- Los clientes 81 y 100 tienen el máximo de 6 pedidos.
Reto
-- ========================================================== -- EJERCICIOS DE AGRUPAMIENTOS CON FILTROS (HAVING) -- Tienda Latam -- ========================================================== -- EJERCICIO 1: Categorías con más de diez productos SELECT c.nombre_categoria AS "Categoría", COUNT(*) AS "Cantidad productos" FROM productos AS p JOIN categorias AS c ON c.categoria_id = p.categoria_id GROUP BY c.nombre_categoria HAVING COUNT(*) > 10 ORDER BY "Cantidad productos" DESC; -- EJERCICIO 2: Países con más de cien clientes SELECT p.nombre_pais AS "Pais", COUNT(*) AS "No. Clientes" FROM clientes AS cli JOIN paises AS p ON p.pais_id = cli.pais_id GROUP BY p.nombre_pais HAVING COUNT(*) > 100 ORDER BY "No. Clientes" DESC; -- EJERCICIO 3: Clientes con más de tres pedidos SELECT c.nombre AS "Nombre", c.apellido AS "Apellido", COUNT(*) AS "No. Pedidos" FROM pedidos AS p JOIN clientes AS c ON c.cliente_id = p.cliente_id GROUP BY c.cliente_id, c.nombre, c.apellido HAVING COUNT(*) > 3 ORDER BY "No. Pedidos" DESC;