🧪 Taller de Laboratorio
vistas

Agregación y Vistas en Vivo: Resúmenes Reales

Otra vez PostgreSQL de verdad, compilado a WebAssembly, corriendo enteramente en tu navegador. Esta vez vas a convertir 14 ventas sueltas en resúmenes por categoría y por vendedor, filtrar esos resúmenes ya calculados, y guardarlos bajo un nombre con vistas — viendo en cada paso exactamente qué calcula el motor.

RC
Ing. Roy Carrasco
Facultad de Ingeniería de Sistemas · UAB

Bienvenido

Este taller es la práctica de laboratorio de agregación (GROUP BY/HAVING) y vistas en PostgreSQL. No vuelve a explicar la teoría desde cero —asume que ya viste la guía— y en cambio te da un PostgreSQL real para escribir cada consulta, viendo exactamente qué filas agrupa, cuáles filtra y qué guarda cada vista.

📎 Prerrequisito

Si todavía no viste la teoría, repasa primero Agregación y Vistas antes de continuar. Este taller usa una sola tabla —ventas, con 14 filas— pensada para que cada resumen se vea clarísimo, sin el ruido de un catálogo completo.

⚠️ Todo vive en la memoria de esta pestaña

Esta página corre su propia base de datos, independiente de cualquier otro taller que hayas abierto antes. Existe solo mientras esta pestaña siga abierta: si recargas la página, la cierras, o navegas a otra guía, se pierde todo y hay que empezar de nuevo desde "Prepara tu base de datos". Si te equivocás y querés reiniciar sin recargar, usa el botón "Reiniciar base de datos" de abajo.

✍️ Lo escribís vos

Cada bloque parte vacío. El enunciado te dice qué tenés que lograr — el código SQL lo escribís de cero.

🩻 Errores reales

Los mensajes de error que vas a ver son exactamente los que da PostgreSQL en producción.

🔢 14 ventas, 4 vendedores, 4 categorías

Suficientes filas para que agrupar por categoría o por vendedor dé resultados distintos entre sí — y para que HAVING tenga algo real que filtrar.

La base de datos está vacía. Baja a "Prepara tu base de datos" para empezar.

Zona de pruebas libres

Este bloque queda disponible durante toda la guía. Usalo en cualquier momento para probar una idea propia, revisar el estado de una tabla con SELECT * FROM tabla;, o experimentar con algo que se te ocurra a mitad de un ejercicio — sin desordenar los bloques guiados.

🧪 Escribe cualquier sentencia SQL

Prepara tu base de datos

Este bloque no es un ejercicio — ya viene resuelto. Crea una tabla, ventas, con 14 filas de ejemplo. Ejecútalo tal cual, una sola vez, antes de seguir.

Qué hace este bloque

Crea ventas con columnas vendedor, categoria y monto: 4 vendedores (Marisol, Iván, Daniela, Esteban) repartidos en 4 categorías (Electrónica, Ropa, Hogar, Deportes), con montos distintos entre sí para que cada resumen agrupado dé un número distinto y fácil de verificar a ojo.

🏗️ Ejecuta esta preparación tal cual
Confirma los datos

El resultado final debería mostrarte 14 filas. Si contás menos o más, usa "🔄 Reiniciar base de datos" y vuelve a ejecutar este bloque — el resto del taller asume exactamente estos datos.

1. GROUP BY

Un grupo por cada valor distinto de la columna elegida, con una función de agregación calculada dentro de cada grupo.

Enunciado — 1.1

Escribe un SELECT que agrupe ventas por categoria, trayendo categoria, COUNT(*) AS ventas y SUM(monto) AS total.

🗄️ Ejercicio 1.1 — GROUP BY categoria
Contá las filas

Deberían salir 4 filas, una por cada categoría distinta — sin importar que la tabla completa tenga 14 filas.

Enunciado — 1.2

Ahora agrupa por vendedor en vez de categoria, trayendo vendedor, COUNT(*) AS ventas, SUM(monto) AS total y AVG(monto) AS promedio.

🗄️ Ejercicio 1.2 — GROUP BY vendedor con varias funciones

1.3 — Antes de ejecutar, predice: ¿cuántas filas devuelve SELECT COUNT(*) FROM ventas (sin GROUP BY)? ¿Y cuántas devuelve SELECT categoria, COUNT(*) FROM ventas GROUP BY categoria? Escribe las dos consultas en este mismo editor, una debajo de otra, para comprobarlo.

🗄️ Ejercicio 1.3 — Predice y comprueba con dos consultas

2. HAVING

Filtrar los grupos ya calculados, después de agrupar — no las filas individuales de la tabla.

Enunciado — 2.1

Repite el ejercicio 1.1 (GROUP BY categoria con COUNT y SUM) y agrégale HAVING SUM(monto) > 700 para quedarte solo con las categorías que vendieron más de Bs 700 en total.

🗄️ Ejercicio 2.1 — HAVING sobre el total por categoría
Solo dos categorías

Deberían quedar Electrónica y Deportes. Ropa (Bs 300) y Hogar (Bs 645) no superan los Bs 700 del filtro, así que HAVING las descarta.

Enunciado — 2.2

Agrupa por vendedor y agrega HAVING COUNT(*) >= 4 para quedarte solo con quienes hicieron 4 o más ventas.

🗄️ Ejercicio 2.2 — HAVING sobre la cantidad de ventas
Enunciado — 2.3

Combina los tres filtros en una sola consulta: primero WHERE monto > 100 (descarta ventas chicas antes de agrupar), después GROUP BY vendedor, y por último HAVING COUNT(*) >= 3 (vendedores con al menos 3 ventas grandes).

🗄️ Ejercicio 2.3 — WHERE + GROUP BY + HAVING juntos
Cada filtro en su momento

Deberían quedar Marisol e Iván. Daniela y Esteban pierden una de sus ventas grandes al aplicar el WHERE (les queda una venta de Bs 100 o menos fuera del conteo), y terminan con menos de 3 ventas grandes cada uno.

3. ORDER BY y LIMIT sobre grupos

El resultado ya agregado se puede ordenar y recortar exactamente igual que filas comunes.

Enunciado — 3.1

Sobre GROUP BY categoria con SUM(monto) AS total, ordena de mayor a menor y quedate con las 2 categorías que más vendieron usando LIMIT 2.

🗄️ Ejercicio 3.1 — Top 2 categorías
Enunciado — 3.2

Sobre GROUP BY vendedor con SUM(monto) AS total, encuentra al vendedor con menos ventas totales usando ORDER BY total ASC y LIMIT 1.

🗄️ Ejercicio 3.2 — El vendedor con menos ventas totales
Una sola fila

Debería salir Daniela, con Bs 880 — el total más bajo de los cuatro vendedores.

4. Vistas

Guardar una consulta con nombre, para no reescribirla cada vez que alguien la necesita.

Enunciado — 4.1

Crea una vista llamada resumen_vendedores a partir de la consulta del ejercicio 1.2: vendedor, COUNT(*) AS ventas, SUM(monto) AS total y AVG(monto) AS promedio, agrupando por vendedor.

🗄️ Ejercicio 4.1 — CREATE VIEW resumen_vendedores
Enunciado — 4.2

Consulta la vista completa con SELECT * FROM resumen_vendedores;. Confirma que el resultado es idéntico al del ejercicio 1.2.

🗄️ Ejercicio 4.2 — Consultar la vista
Enunciado — 4.3

Sobre la vista, agrega WHERE total > 900 para quedarte solo con los vendedores que más vendieron. Ojo: acá es WHERE, no HAVING — para la vista, total ya es una columna común.

🗄️ Ejercicio 4.3 — Filtrar la vista con WHERE
Tres vendedores

Deberían quedar Marisol (Bs 1435), Iván (Bs 1420) y Esteban (Bs 925). Daniela (Bs 880) no supera los Bs 900 del filtro.

Enunciado — 4.4

Actualiza la vista con CREATE OR REPLACE VIEW resumen_vendedores, agregando MAX(monto) AS venta_max a las columnas que ya tenía. Después vuelve a consultarla completa con SELECT * para confirmar que la columna nueva aparece.

🗄️ Ejercicio 4.4 — CREATE OR REPLACE VIEW
Sin borrar nada

La vista no se borró ni se recreó desde cero: CREATE OR REPLACE VIEW actualizó su definición en el lugar. La consulta del ejercicio 4.3 seguiría funcionando igual si la volvieras a ejecutar, ahora con una columna más disponible.

Reto final: de la tabla a la vista

Sin reiniciar la base de datos, resuelve estos tres desafíos combinando GROUP BY, HAVING y vistas.

Requisitos
  • 1. Con GROUP BY categoria, trae categoria, COUNT(*) AS ventas y SUM(monto) AS total para las 4 categorías, ordenado por total de mayor a menor.
  • 2. Con GROUP BY vendedor y HAVING, encuentra a los vendedores cuyo total de ventas supere Bs 900.
  • 3. Crea una vista llamada top_categorias que guarde el resultado del punto 1, pero recortado a las 2 categorías de mayor total (con ORDER BY y LIMIT dentro de la propia vista), y consúltala al final con SELECT *.
🏆 Resuelve aquí el reto

Repaso

Seis preguntas cortas sobre lo que acabas de observar en vivo. Tu progreso se guarda automáticamente en este navegador.

0 / 0
actividades correctas en toda la guía
Selección múltiple

En el ejercicio 1.1 agrupaste las ventas por categoría. ¿Cuántas filas devolvió esa consulta, y por qué?

Selección múltiple

En el ejercicio 2.1 agregaste HAVING SUM(monto) > 700 sobre el GROUP BY por categoría. ¿Qué categorías quedaron afuera, y por qué?

Clasificación

Clasifica cada fragmento de consulta según qué hace.

WHERE monto > 100
GROUP BY vendedor
HAVING COUNT(*) >= 4
WHERE vendedor = 'Marisol'

Completar

Sobre el ejercicio 2.3 (WHERE monto > 100, GROUP BY vendedor, HAVING COUNT(*) >= 3).

1. El primer filtro en aplicarse, antes de que exista ningún grupo, es .

2. El filtro que se aplica al final, sobre los grupos ya armados, es .

Selección múltiple

En el ejercicio 4.4 actualizaste la vista con CREATE OR REPLACE VIEW, agregando MAX(monto). ¿Qué pasó con la consulta del ejercicio 4.3, que ya usaba resumen_vendedores antes de ese cambio?

Emparejamiento

Une cada cláusula con lo que hace en una consulta con agregación.

Cheat Sheet del taller

FormaPara qué sirve
GROUP BY columnaAgrupa filas que comparten el mismo valor en esa columna.
COUNT() / SUM() / AVG() / MAX() / MIN()Funciones de agregación: un valor por grupo (o por toda la tabla, sin GROUP BY).
WHEREFiltra filas individuales, antes de agrupar.
HAVINGFiltra grupos ya calculados, después de agrupar.
... GROUP BY col ORDER BY total DESC LIMIT nOrdena y recorta el resultado ya agregado.
CREATE VIEW nombre AS SELECT ...Guarda una consulta con nombre; no copia datos.
SELECT * FROM vistaSe consulta como una tabla común.
CREATE OR REPLACE VIEW ...Reemplaza la definición de una vista sin borrarla.

¿Sabías que...?

🧮 GROUP BY sin ORDER BY no promete ningún orden

El orden en que aparecieron las categorías en este taller es el que decidió PostgreSQL internamente, no uno garantizado por el estándar SQL. Si el orden importa para tu resultado, siempre hay que agregar un ORDER BY explícito.

🔒 Las vistas también sirven para seguridad

En vez de dar acceso directo a ventas completa, se le podría dar a alguien acceso solo a resumen_vendedores — ve los totales, no cada venta individual. Un adelanto de lo que vas a ver en la guía de roles y GRANT/REVOKE.

💾 Existen las vistas materializadas

A diferencia de las vistas de este taller, una vista materializada (MATERIALIZED VIEW) sí guarda una copia física del resultado, que hay que refrescar a mano — útil cuando la consulta original es cara de recalcular cada vez.