pedidos únicos. La tabla final preserva exactamente una fila por pedido.
¿Dónde llegan tarde los pedidos?
Modelé pedidos, vendedores y reseñas de Olist para medir entregas posteriores a la fecha prometida sin duplicar pedidos al cruzar tablas.
Olist · Brasil · Pedidos históricos 2016–2018 · dbt validado localmente en DuckDB
pedidos con fecha real y prometida
filas al unir directamente pedidos, ítems, pagos y reseñas sin resolver sus granularidades.
entre los pedidos tardíos con reseña, puntuación de 1 o 2. Es una asociación descriptiva.
Una misma demora, dos lecturas.
Comparé tasa y cantidad porque responden preguntas distintas: dónde es más frecuente el atraso y dónde se acumulan más pedidos afectados.
Entregas tardías por estado
Antes de recomendar cambios, comprobé dónde aparece la diferencia.
Tomé el mes de compra y comparé meses completos de 2018. En marzo, 1.328 de 7.003 entregas evaluables llegaron después de la fecha prometida: 18,96%. En enero fueron 403 de 7.069: 5,70%. La diferencia merece revisar si cambiaron los plazos prometidos, la mezcla de destinos o los tiempos de entrega. No elegiría una causa solo por ver el salto en la serie.
También crucé atraso con reseñas para medir si ambos fenómenos aparecen juntos. Entre los pedidos con reseña, 62,42% de los tardíos recibió 1 o 2 puntos, frente a 9,27% de los entregados a tiempo. Es una señal para investigar la experiencia del cliente, pero la reseña es opcional y la comparación no demuestra que la demora causó la nota.
Mi siguiente paso sería revisar por estado y mes los pedidos, las fechas prometidas y el tiempo real de entrega. Mantendría separados los 1.278 pedidos con varios vendedores: la fecha de entrega pertenece al pedido completo y no alcanza para responsabilizar a uno de ellos.
Primero resolví qué representa cada fila.
Detecté duplicaciones
Partí de 99.441 pedidos. Al unir directamente ítems, pagos y reseñas obtuve 119.143 filas, 19,8% más. Esa multiplicación habría alterado tasas y recuentos, así que no la usé para medir atrasos.
Volví al pedido
Resumí los vendedores por order_id y conservé la última respuesta de reseña por pedido. Recién después uní esas tablas con pedidos y clientes; el resultado mantiene una fila por order_id.
Definí el atraso
Solo evalué pedidos entregados con fecha real y prometida. Comparé las fechas calendario: 6.534 de 96.470 llegaron después de lo prometido, 6,77%. Si falta una fecha, dejo el indicador sin evaluar.
Comprobé el grano
Ejecuté 9 modelos y 25 pruebas dbt sobre claves, relaciones, unicidad y lógica del indicador. El build terminó sin fallos en DuckDB; Snowflake sigue pendiente.
Del CSV a una métrica que se puede comprobar.
Construí un flujo con source() y ref(): fuentes → staging → preparación por pedido → tabla de entregas → agregados. Cada modelo resuelve una parte del problema y dbt ordena sus dependencias.
1. Preparé el grano antes de unir tablas
En staging convertí fechas y puntuaciones a tipos utilizables. Las reseñas podían repetirse por pedido: conservé la última respuesta con ROW_NUMBER(). Agrupé los ítems por order_id para contar vendedores sin multiplicar pedidos.
ROW_NUMBER() OVER (
PARTITION BY order_id
ORDER BY TRY_CAST(review_answer_timestamp AS TIMESTAMP) DESC NULLS LAST,
review_id DESC
) AS review_rank
-- Después: WHERE review_rank = 12. Definí la regla de atraso y la probé
La tabla fct_order_delivery une esas fuentes ya preparadas y conserva una fila por pedido. is_late compara fechas calendario solo si el pedido fue entregado y tiene ambas fechas; en los demás casos queda nulo.
CASE
WHEN o.order_status = 'delivered'
AND o.delivered_at IS NOT NULL
AND o.promised_at IS NOT NULL
THEN CAST(o.delivered_at AS DATE) > CAST(o.promised_at AS DATE)
ELSE NULL
END AS is_lateDespués construí los agregados por mes, estado y vendedor. Ejecuté dbt build en DuckDB: pasaron 9 modelos y 25 pruebas de claves, relaciones, unicidad y lógica del indicador. El ejemplo de código resume los modelos originales, disponibles para descargar; la ejecución en Snowflake sigue pendiente.
Olist Brazilian E-Commerce Public Dataset, licencia CC BY-NC-SA 4.0. Modelo dbt ejecutado en DuckDB con datos históricos de 2016–2018. El perfil para Snowflake está preparado; su ejecución está pendiente.
¿Necesitás métricas en las que se pueda confiar?
Diseño modelos, controles y análisis que dejan claro qué se cuenta y qué decisión permiten tomar.