Proyecto 3 de Tripleten: Análisis de desempeño financiero con SQL
Análisis del desempeño financiero de Adventure Works con SQL
El presente análisis tiene como
objetivo evaluar el desempeño financiero de Adventure Works mediante el uso de
consultas SQL, con el fin de identificar los mercados que generan mayores
ingresos y rentabilidad. A partir de la información proveniente de órdenes,
productos, territorios y campañas de marketing, se busca ofrecer una base
analítica que respalde decisiones estratégicas sobre la asignación óptima del
presupuesto comercial.
El proyecto permite al analista
desarrollar competencias clave en la navegación de esquemas relacionales, la
combinación de tablas mediante JOINs, y la aplicación de técnicas de limpieza y
transformación de datos —incluyendo la gestión de valores nulos, conversiones
de tipo y estandarización de categorías—. Además, se calcularán indicadores
financieros fundamentales como ingresos, costos, beneficio bruto, márgenes y
retorno sobre la inversión (ROI), complementados con controles de calidad y
validaciones cruzadas.
Utilizando un subconjunto del
conjunto de datos de AdventureWorks, que incluye tablas de ventas, productos,
categorías, clientes, territorios y campañas, el análisis busca responder dos
preguntas esenciales para la dirección financiera: ¿cuánto estamos ganando por
país? y ¿qué tan rentable es cada mercado considerando los gastos de marketing?
Finalmente, los resultados se
sintetizarán en un informe ejecutivo siguiendo el método Contexto → Hallazgo →
Implicación (C→F→I), acompañado de visualizaciones que faciliten la
interpretación de las conclusiones y la identificación de oportunidades de
inversión.
Parte 1: Explorar el esquema
1. Imprime
los 10 primeros renglones de la tabla ventas_2017.
CODIGO
SELECT*
FROM VENTAS_2017
LIMIT 10;
2. Imprime
los 10 primeros renglones de la tabla productos.
CODIGO
SELECT*
FROM territorios
limit 10;
3. Imprime
los 10 primeros renglones de la tabla productos categorías.
CODIGO
SELECT*
FROM territorios
limit 10;
4. Imprime
los 10 primeros renglones de la tabla territorios.
CODIGO
SELECT*
FROM territorios
limit 10;
5. Imprime
los 10 primeros renglones de la tabla campanas
CODIGO
SELECT*
FROM campanas
LIMIT 10;
Parte 2: Extraer y limpiar datos
1. Unión
de Tablas: Piensa qué datos necesitas tener en una sola tabla para responder a
las preguntas del director financiero (¿cuánto se vende, a qué precio, con qué
costo, y en qué país?).
Instrucciones
Generales: Une las tablas
- ventas_2017 v con
productos p,
- productos p
con productos categorías pc,
- ventas_2017 v con territorios t
CODIGO
SELECT
v.numero_pedido,
v.clave_producto,
p.nombre_producto,
pc.clave_categoria,
p.precio_producto,
v.cantidad_pedido,
p.costo_producto,
t.pais,
t.continente,
v.clave_territorio
FROM
ventas_2017 AS v
productos AS p,
productos_categorias AS pc
territorio AS t;
2. Cálculo
de ingresos y costos: Tu tarea en este paso es crear dos nuevas columnas
calculadas:
Instrucciones
Generales
Añade la columna
ingreso total → precio de cada producto × cantidad pedida.
Añade la columna
costo total → costo de cada producto × cantidad pedida.
No se te olvide
reemplazar nulos por ceros para evitar errores.
CODIGO
SELECT
v.numero_pedido,
v.clave_producto,
p.nombre_producto,
pc.clave_categoria,
COALESCE(p.precio_producto, 0) AS precio_producto,
COALESCE(v.cantidad_pedido, 0) AS cantidad_pedido,
COALESCE(p.costo_producto, 0) AS costo_producto,
t.pais,
t.continente,
v.clave_territorio,
COALESCE(p.precio_producto, 0) *
COALESCE(v.cantidad_pedido, 0) AS ingreso_total,
COALESCE(p.costo_producto,
0)*COALESCE(v.cantidad_pedido, 0) AS costo_total
FROM ventas_2017 AS v
JOIN productos AS p
ON v.clave_producto = p.clave_producto
LEFT JOIN productos_categorias
AS pc
ON p.clave_subcategoria = pc.clave_subcategoria
LEFT JOIN territorios AS t
ON v.clave_territorio = t.clave_territorio;
Parte 3: Calcular KPIs financieros
1.
Calcular
ingresos y costos por país
Objetivo: Muy bien, hemos grabado tu
query como una tabla en la base de datos con el nombre ventas clean. Ahora
puedes utilizarla como la base para continuar con los siguientes pasos.
Queremos calcular el total de ingresos y costos en cada país.
Instrucciones Generales
Selecciona y agrupa por el país y
clave del territorio de la tabla ventas_clean
Suma los ingresos y costos. Utiliza
el alias ingresos y costos respectivamente.
añade:: integer a ingreso_total y
costo_total para obtener montos legibles.
Y ordena para ver primero los países
más grandes en ventas.
CODIGO
select
pais,
clave_territorio,
SUM(ingreso_total)::integer
AS ingresos,
SUM(costo_total)::integer
AS costos
FROM
ventas_clean
GROUP
BY pais, clave_territorio
ORDER
BY ingresos DESC;
2.
Agregar
la inversión en campañas de marketing
Objetivo: Ya sabes cuánto entra
(ingresos) y cuánto cuesta operar (costos).
Pero aún nos falta una pieza clave:
¿cuánto estamos gastando en campañas de marketing?
La idea es combinar lo que venden los
países con lo que se invirtió en campañas, para ver la foto completa.
Instrucciones Generales
Suma el costo por campaña.
Nombra la columna costo_campana.
Y no se te olvide reemplazar valores
nulos por cero.
utiliza ::integer para convertir el
valor de la campaña a número entero.
CODIGO
SELECT
v.pais,
v.clave_territorio,
SUM(v.ingreso_total)::integer AS ingresos,
SUM(v.costo_total)::integer AS costos,
COALESCE(SUM(c.costo_campana::integer)
,0) AS costo_campana
FROM
ventas_clean AS v
LEFT
JOIN campanas AS c
ON v.clave_territorio =
c.clave_territorio::integer
GROUP
BY
v.pais,
v.clave_territorio
ORDER
BY
ingresos DESC;
3.
Calcular
Beneficio Bruto, Margen y ROI
Muy bien, hemos grabado tus queries
de los pasos anteriores en la base de datos con el nombre pais_ingreso_costo y
pais_campanas.
Objetivo: Ya tenemos ventas, costos y
campañas. Ahora toca transformarlos en indicadores que hablan el idioma del
negocio.
Instrucciones Generales
Calcula el beneficio_bruto (ganancia
antes de marketing) → ¿cuánto sobra después de cubrir costos directos?
Calcula el margen_pct (eficiencia de
ventas) → ¿qué porcentaje de cada dólar vendido se queda como ganancia bruta?
Calcula el roi_pct (retorno sobre
campañas) → ¿qué tan rentable es cada peso invertido en marketing?
CODIGO
SELECT
p.pais,
p.clave_territorio,
SUM(p.ingresos)::integer AS ingresos,
SUM(p.costos)::integer AS costos,
COALESCE(SUM(c.costo_campana), 0)::integer
AS costo_campana,
SUM(p.ingresos)::integer
- SUM(p.costos)::integer AS beneficio_bruto,
((SUM(p.ingresos) - SUM(p.costos))* 100.0) /
NULLIF(SUM(p.ingresos), 0) AS margin_pct,
((SUM(p.ingresos) - SUM(p.costos)) * 100.0) /
NULLIF (SUM(c.costo_campana), 0) AS ROI_pct
FROM
pais_ingreso_costo AS p
LEFT
JOIN pais_campanas AS c
ON p.clave_territorio = c.clave_territorio
GROUP
BY
p.pais,
p.clave_territorio
ORDER
BY
p.clave_territorio, ingresos, costos;
Parte 4 - Validar resultados y QA
1.
Validar
integridad básica — NULOS en claves
Cuando tu proceso integra ventas con
productos y territorios, cualquier clave faltante puede romper uniones o
distorsionar sumas. Vamos a realizar un chequeo rápido de integridad para
confirmar que no existan valores nulos en las columnas clave.
Objetivo: Detectar valores NULL en
las claves mínimas necesarias para unir y agrupar correctamente los datos.
Instrucciones Generales
Evalúa las tres claves principales en
ventas_2017:
numero_pedido
clave_producto
clave_territorio
Usa SUM(CASE WHEN .... THEN ... ELSE
... END) para contar nulos por columna.
Si algún conteo > 0, detén el
proceso y revisa antes de continuar.
CODIGO
SELECT
SUM
(CASE WHEN numero_pedido IS NULL THEN 1 ELSE 0 END) AS nulos_numero_pedido,
SUM
(CASE WHEN clave_producto IS NULL THEN 1 ELSE 0 END) AS nulos_clave_producto,
SUM
(CASE WHEN clave_territorio IS NULL THEN 1 ELSE 0 END) AS
nulos_clave_territorio
FROM
ventas_2017;
2.
Validar
valores no válidos en ventas_2017 (cantidad)
Algunas integraciones pueden incluir
devoluciones o errores que dejan cantidades en cero o negativas, afectando los
totales. Vamos a contar las filas problemáticas para garantizar que los datos
de ventas sean consistentes.
Objetivo: Detectar registros con
cantidad_pedido igual o menor que cero.
Instrucciones Generales
Usa la tabla ventas_2017.
Filtra casos donde la cantidad del
pedido sea menor o igual a cero.
Cuenta las filas resultantes con
COUNT(*). Asigna el alias filas_cantidad_no_valida.
CODIGO
SELECT
COUNT(*)
AS filas_cantidad_no_valida
FROM
ventas_2017
WHERE
cantidad_pedido <= 0;
3.
Validar
precios en productos
Antes de calcular ingresos,
confirmemos que los precios en el catálogo no tengan valores negativos o
inconsistentes. Los precios negativos suelen indicar errores de carga o
descuentos mal definidos.
Objetivo: Detectar registros en
productos con precios negativos.
Instrucciones Generales
Usa la tabla productos.
Filtra donde el precio del producto
sea menor a cero.
Cuenta las filas resultantes con
COUNT(*). Asigna el alias productos_precio_no_valido.
CODIGO
SELECT
COUNT(*)
AS productos_precio_no_valido
FROM
productos
WHERE
precio_producto < 0;
Parte 5 - Resumen ejecutivo
Llegamos al último paso: preparar un informe ejecutivo para
el director de finanzas.
Recuerda que todo el análisis busca responder a las dos
preguntas iniciales:
¿Cuánto estamos ganando por país?
¿Qué tan rentable es cada mercado considerando los gastos de
marketing?
Para ello, vas a trabajar con la tabla que ya construiste con
ingresos, costos, margen y ROI.
1.
Resumen
ejecutivo (1 página, estilo C → F → I):
Contexto: Explica en 3–4 frases qué analizaste y con qué
datos trabajaste.
Hallazgos: Incluye 3–4 conclusiones clave (ejemplo: país más
rentable, mercado con menor margen, campañas poco efectivas).
Ideas accionables: Propón 2 recomendaciones claras para el
negocio (ejemplo: aumentar inversión en país A, revisar estructura de costos en
país B).
2.
Reflexión
personal: Contesta brevemente estas preguntas para consolidar tu comprensión:
¿En qué se diferencian el Margen y el ROI?
¿Por qué crees que el ROI en Estados Unidos es mucho más alto
que en otros países?
Si aumentáramos el gasto de campañas en un 50%, ¿qué pasaría
con el ROI?




