La idea
Pregunta "¿cuáles fueron los ingresos de 2025?" y puedes obtener al menos tres respuestas correctas de la misma base de datos: $2,410,186, $2,362,232 o $2,221,363. Nadie se equivoca. Cada cifra se construye con una regla distinta, y la regla es la métrica.
Toda cifra de ingresos responde tres preguntas. ¿Qué pedidos cuentan? ¿Qué precio usas: el de la etiqueta o lo que el cliente pagó tras los descuentos? ¿Y devuelves crédito cuando un pedido se devuelve? Cambia cualquier respuesta y el número cambia.
Figura 1
De todos los pedidos de 2025 a los ingresos netos: una regla por paso
- Todos los pedidos 4,783 hechos en 2025
- Pedidos contabilizados completed o refunded: 4,409
- Ventas brutas quantity × unit_price
- Ventas netas brutas menos descuentos
- Ingresos netos ventas netas menos reembolsos
- Empieza con todos los pedidos hechos en 2025: 4,295 completed, 114 refunded, 275 cancelled y 99 pending. Cuatro estados, 4,783 pedidos.
- Solo cuentan los pedidos contabilizados:
completedorefunded. Los cancelados nunca se pagaron y los pendientes aún no se liquidan, así que aquí salen 374 pedidos. - En los pedidos contabilizados, suma
quantity * unit_pricede cada línea válida (cantidad mayor que cero). Eso son las ventas brutas: $2,410,185.52. - Resta los descuentos de línea, el
discount_pctde cada una. Con $47,953.28 de descuentos, las ventas netas son $2,362,232.24. - Por último resta los reembolsos pagados sobre las líneas de esos pedidos: $140,869.57. Los ingresos netos son $2,221,362.67. Los gastos de envío nunca entraron en la escalera.
Piénsalo como una escalera. Siempre empiezas en el peldaño de arriba con todo lo que se vendió, y cada peldaño que bajas aplica una regla que quita algo. Cuanto más bajas, más cuidadosa es la cifra y menos se parece a la que figura en la etiqueta del precio.
Por qué existe
Cada persona necesita una cifra distinta. Quien gestiona el surtido y pregunta "¿cuánto pusimos a la venta?" quiere las ventas brutas. Quien hace marketing y pregunta "¿cuánto costaron los cupones?" necesita las brutas y las netas lado a lado. Quien lleva las finanzas y debe pagar las cuentas quiere los ingresos netos, porque el dinero reembolsado ya no está.
Si esas tres cifras circulan sin etiqueta, cada reunión termina en una discusión sobre quién tiene la hoja de cálculo correcta. Harbor & Pine lo resuelve escribiendo la regla una vez y usándola en todas partes. En esta ruta la regla es:
- Línea válida:
order_items.quantity > 0. Las 24 líneas con cantidad cero o negativa son errores de captura. - Pedido contabilizado:
status IN ('completed', 'refunded'). - Ventas brutas = Σ
quantity * unit_priceen las líneas válidas de pedidos contabilizados. - Ventas netas = brutas − Σ descuentos de línea, donde el descuento de una línea es su importe
bruto ×
discount_pct / 100. - Ingresos netos = ventas netas − Σ
returns.refund_amount. Sin gastos de envío. - Año:
order_datedentro del año natural; un reembolso cuenta en el año del pedido, no en el del reembolso.
La última regla importa más de lo que parece. Un sofá vendido el 28 de diciembre y devuelto el 20 de enero es una venta de 2025 y un reembolso de 2025. Si el reembolso se anotara en enero, 2025 se vería mejor de lo que fue y enero peor de lo que fue, por una decisión tomada en el otro mes. Mantener el reembolso junto a su pedido hace que cada año sea honesto con sus propias ventas.
Cómo funciona por dentro
Paso 1: decidir qué pedidos cuentan
La tabla orders tiene todos los pedidos que se han iniciado, y su columna status es el filtro.
Contabilizado significa que el cliente pagó. Los cancelled nunca se cobraron; los pending todavía
pueden cancelarse. refunded se queda a propósito: primero se cobró el dinero y el reembolso se resta
después, en su propio paso. Si descartas los reembolsados en el primer paso, quitas la venta y el
reembolso a la vez, y tus ingresos netos quedan demasiado altos.
Paso 2: poner precio a las líneas, no a los pedidos
Los ingresos viven en order_items, una fila por producto de cada pedido. Multiplica quantity por
unit_price en cada línea y luego suma. No multipliques un conteo de pedidos por un precio medio: los
descuentos cambian de línea en línea, y la línea es la unidad en que se registran.
Paso 3: restar los reembolsos desde el lugar correcto
Un reembolso es una fila de returns, ligada a un order_item_id. Para ponerlo en la escalera lo
unes a las líneas, normalmente con un LEFT JOIN, porque la mayoría de las líneas nunca se devuelven y
un INNER JOIN las descartaría en silencio. Después sumas refund_amount. En 2025 son 616 líneas
devueltas por $140,869.57.
Figura 2
Los mismos pedidos de 2025, tres cifras de ingresos
- Las ventas brutas son lo que suman las etiquetas de precio, antes de restar nada.
- Las ventas netas son $47,953 menos (2.0%): los descuentos que la tienda regaló en caja.
- Los ingresos netos son otros $140,870 menos (6.0% de las ventas netas). Un reembolso es dinero real que salió, aunque el pedido estuviera contabilizado.
- Una diferencia de $188,823 entre la barra más alta y la más baja, con pedidos idénticos. Unos 'ingresos' sin definición pueden ser cualquiera de los tres.
Las razones heredan la definición
Una vez fijada la escalera, toda razón construida encima queda fijada también. La única decisión que queda es la división, y la regla es simple: suma primero arriba y abajo, y divide una sola vez.
El valor medio del pedido (AOV) son las ventas netas entre los pedidos contabilizados: $2,362,232.24 /
4,409 = $535.78. Cuenta pedidos con COUNT(DISTINCT order_id), nunca líneas, o un pedido de tres
líneas cuenta tres veces. La tasa de descuento es el descuento total entre el bruto total:
$47,953.28 / $2,410,185.52 = 1.99%. Si promedias la tasa de descuento de cada pedido obtienes otro
número, porque entonces los pedidos pequeños pesan tanto como los grandes.
Cómo revisar tu propia cifra
Dos comprobaciones atrapan la mayoría de los errores. Primero, recorre la escalera en orden y asegúrate
de que cada peldaño sea menor que el de arriba: si las ventas netas superan a las brutas, un join ha
repetido líneas. Segundo, compara tus ventas brutas con un simple SUM de todas las líneas válidas sin
el filtro de estado. La diferencia debe ser igual a las ventas de los pedidos cancelados y pendientes.
Si no lo es, algún filtro oculta o agrega algo que no querías.
Errores comunes
"Los ingresos son la suma de la tabla de pedidos"
La tabla de pedidos no tiene dinero. Los precios están en order_items y los reembolsos en returns.
Y aun así, sumar todas las líneas incluye pedidos cancelados y pendientes: en 2025 solo los pedidos
cancelados sumarían $158,503 de ventas que nunca se pagaron. Di siempre qué estados contaste.
"Cancelado y reembolsado son lo mismo"
Un pedido cancelado nunca ocurrió en términos financieros. Uno reembolsado sí: el cliente pagó y luego recuperó su dinero. Por eso uno se filtra y el otro se resta. Si los tratas igual, la tasa de reembolsos o los ingresos salen mal.
"Los ingresos netos son mejores que las ventas brutas"
Son otra cifra. Las ventas brutas responden "¿qué eligieron comprar los clientes a precio de lista?"; los ingresos netos responden "¿con qué nos quedamos?". Un puente de una a otra (brutas, menos descuentos, menos reembolsos) sirve más que cualquiera de las dos, porque muestra adónde fueron $188,823.
Ponte a prueba
Una pregunta. Al responderla, la lección queda marcada en el mapa; nunca bloquea un nivel.
No del todo. Los pedidos reembolsados sí están contabilizados: el cliente pagó. Excluirlos también ocultaría los reembolsos y la tasa de devoluciones se vería mejor de lo que es.Prueba otra respuesta.
Correcto. El pedido se pagó, así que sus líneas cuentan en las ventas brutas y netas. El reembolso de returns se resta después, y los ingresos netos de ese pedido quedan cerca de cero.
No del todo. Los ingresos netos parten de las ventas netas, así que primero hay que contar las líneas ahí. El reembolso solo las quita después.Prueba otra respuesta.
No del todo. Los descuentos están en la línea, así que las ventas netas los incluyen en todo pedido contabilizado. El reembolso se resta en los ingresos netos.Prueba otra respuesta.
Lección hecha: ya está marcada en el mapa.