SQL Intermedio · Lección 3 de 6
Reportes con JOIN y subconsultas
Unir tablas sirve de verdad cuando lo combinás con lo que ya sabés: sumar, contar y agrupar. Y con una subconsulta encontrás lo que falta.
JOIN + GROUP BY = un reporte
Ya sabés agrupar con GROUP BY y sumar con SUM. Con JOIN, ahora podés agrupar por nombres en lugar de números: unidades por producto, ventas por sucursal, compras por cliente.
Y aparece una cuenta clave para cualquier negocio: la facturación. La cantidad está en ventas y el precio en productos, así que necesitás el JOIN para multiplicarlos:
SELECT p.categoria,
SUM(v.cantidad * p.precio) AS facturacion
FROM ventas v
JOIN productos p ON v.producto_id = p.id
GROUP BY p.categoria;Se lee: "para cada venta, multiplicá la cantidad por el precio de su producto, y sumalo por categoría". Unís, calculás y agrupás en una sola consulta.
¿Y lo que no se vendió?
Un JOIN trae solo las filas que tienen pareja: un producto que nunca se vendió no tiene ninguna fila en ventas, así que no aparece en el resultado. Para encontrar lo que falta hay un camino muy claro: preguntar qué productos no están en la lista de los vendidos.
Esa lista se arma con una subconsulta: una consulta entre paréntesis, adentro de otra. Primero se resuelve la de adentro (la lista de producto_id que aparecen en ventas) y después la de afuera se queda con los productos cuyo id NOT IN ("no está en") esa lista.
SELECT nombre FROM productos WHERE id NOT IN ( SELECT producto_id FROM ventas );

Con IN, sin el NOT, hacés lo contrario: te quedás con los que sí están en la lista. Por ejemplo, los clientes que compraron en la sucursal Sur.
Actividad 1
¿Lo que pasó o lo que falta?
¿La pregunta es por lo que pasó (se resuelve con JOIN y GROUP BY) o por lo que falta (se resuelve con NOT IN y una subconsulta)? Ubicá cada una.
Lo que pasó
JOIN + GROUP BY
Lo que falta
NOT IN + subconsulta
Actividad 2
Reportes del almacén
Tres reportes que cualquier almacén querría tener. Mirá las tablas antes de escribir.
ventas:idINTEGERfechaDATEcliente_idINTEGERproducto_idINTEGERsucursal_idINTEGERcantidadINTEGERPrimer paso: explorar toda la tabla
Antes de escribir tu consulta, conviene mirar la tabla completa. Esta consulta trae todas las columnas (eso significa el asterisco) y todas las filas:
SELECT * FROM ventas;
Cargando la tabla…
Cada fila es una compra: cuándo, quién, qué, en qué sucursal y cuántas unidades. Fijate que cliente_id, producto_id y sucursal_id no son nombres: son números que apuntan a otra tabla. Para traer esos nombres se usa JOIN.
Hacelo siempre como primer paso cuando trabajes con una tabla nueva. Si la tabla es enorme, sumale LIMIT 20 para ver solo una muestra, como viste en SQL Inicial.
productos:idINTEGERnombreTEXTcategoriaTEXTprecioREALstockINTEGERPrimer paso: explorar toda la tabla
Antes de escribir tu consulta, conviene mirar la tabla completa. Esta consulta trae todas las columnas (eso significa el asterisco) y todas las filas:
SELECT * FROM productos;
Cargando la tabla…
Mirándola te ubicás: qué columnas hay, cómo están escritos los textos (por ejemplo, 'Lácteos' con mayúscula y tilde) y entre qué valores andan los números. Con eso armás tu consulta sin adivinar. Su id es el número que aparece en ventas.producto_id.
Hacelo siempre como primer paso cuando trabajes con una tabla nueva. Si la tabla es enorme, sumale LIMIT 20 para ver solo una muestra, como viste en SQL Inicial.
sucursales:idINTEGERnombreTEXTbarrioTEXTPrimer paso: explorar toda la tabla
Antes de escribir tu consulta, conviene mirar la tabla completa. Esta consulta trae todas las columnas (eso significa el asterisco) y todas las filas:
SELECT * FROM sucursales;
Cargando la tabla…
Las tres sucursales del almacén. Su id es el número que aparece en ventas.sucursal_id.
Hacelo siempre como primer paso cuando trabajes con una tabla nueva. Si la tabla es enorme, sumale LIMIT 20 para ver solo una muestra, como viste en SQL Inicial.
- 1Mostrá el
nombrede cada producto y cuántas unidades se vendieron en total. - 2Mostrá el
nombrede cada sucursal y cuánto facturó (cantidad × precio). - 3Encontrá los productos que nunca se vendieron: mostrá su
nombre. UsáNOT INcon una subconsulta.
Tu misión, las tablas, los mensajes y la ayuda están en el panel de la izquierda.
Tocá Ejecutar para ver el resultado.
Chequeo rápido
¿Qué devuelve esta consulta?
SELECT nombre FROM clientes WHERE id NOT IN ( SELECT cliente_id FROM ventas );
Que la IA te explique una subconsulta
Las consultas con una consulta adentro asustan al principio. Pedile a Gemini que te las lea en castellano:
Explicame esta consulta de adentro hacia afuera, como si nunca hubiera visto una subconsulta, y decime qué devolvería: [pegá acá la consulta con NOT IN]
Después ejecutala vos y fijate si el resultado coincide con lo que te explicó.
SUM(cantidad * precio). Para encontrar lo que falta, una subconsulta arma la lista y NOT IN se queda con lo que no está en ella.Ya armás reportes con varias tablas