lección 6
Sanity checks antes de enseñar una cifra
Las siete comprobaciones rápidas que un analista hace ANTES de presentar un número, para no entregar basura con buena pinta.
⏱ 50 min
Septiembre de 1999. La sonda Mars Climate Orbiter de la NASA lleva nueve meses viajando hacia Marte. Ha costado 327 millones de dólares. Al entrar en órbita, se acerca demasiado a la atmósfera marciana y se desintegra. La investigación posterior revela la causa: un equipo envió los datos de empuje en libras-fuerza multiplicadas por los segundos que duraba el encendido, y el otro equipo los leyó asumiendo que eran newtons multiplicados por segundos. Nadie miró el número y dijo "esto parece raro". Nadie hizo un sanity check.
No vas a perder una sonda de 327 millones. Pero sí vas a perder algo igual de difícil de recuperar: la confianza de tu equipo. La primera vez que presentas un número incorrecto en una reunión, te perdonan. La segunda, empiezan a comprobar todo lo que entregas. La tercera, dejan de pedirte análisis. Y la parte cruel es que el error casi nunca está en la lógica compleja: está en lo básico. Un filtro que se te olvidó. Un duplicado que no viste. Un mes que se coló de más. Errores que se detectan en treinta segundos si los buscas.
Eso es un sanity check: una comprobación rápida de que tu resultado tiene sentido antes de enseñárselo a nadie. No es un test estadístico formal. No es una auditoría exhaustiva. Es el equivalente de oler la comida antes de servirla. No garantiza que esté perfecta, pero te evita servir algo podrido.
### La analogía del restaurante
Un chef no manda un plato a la mesa sin mirarlo. Antes de que salga de la cocina, le echa un vistazo rápido: ¿tiene buena pinta? ¿Huele bien? ¿La temperatura es correcta? ¿No tiene un pelo encima? Esas comprobaciones tardan cinco segundos y no sustituyen al control de calidad del restaurante (inspecciones sanitarias, revisión de proveedores, formación del equipo). Pero evitan casi todas las situaciones embarazosas. Tú eres el chef y el número es tu plato.
### Los 7 sanity checks que haces SIEMPRE
Después de años viendo errores propios y ajenos, la lista se reduce a siete comprobaciones. No son opcionales. No dependen de si tienes prisa. Las haces siempre, como el piloto que repasa su checklist aunque lleve veinte años volando. Porque el piloto sabe algo que el principiante no: los errores no vienen de la dificultad, vienen de la confianza excesiva.
### 1. Orden de magnitud: ¿tiene el tamaño que esperas?
Si el mes pasado fueron 4 millones de euros en ventas y hoy tu query te da 400.000, algo está mal. No necesitas saber exactamente qué: el hecho de que el número sea 10 veces menor ya te dice que hay un problema. Puede ser un filtro de más, una tabla que no se cargó, un JOIN que eliminó filas. Pero el diagnóstico viene después. Lo primero es detectar que el orden de magnitud no cuadra.
La pregunta es: ¿se parece al número que esperaba? No necesitas ser exacto. Si esperas "unos cuantos millones" y te sale "unos cuantos miles", hay un problema. Si esperas "entre 3 y 5 millones" y te sale 4,1, probablemente estás bien. El orden de magnitud es tu primer filtro, el más rápido y el que más errores graves atrapa.
Consejo de senior: antes de ejecutar la query, escribe en un papel (o mentalmente) lo que esperas que salga. No un número exacto: un rango. "Debería estar entre 3 y 5 millones." "Deberían ser unos 40.000 usuarios." Si tu resultado cae fuera de ese rango, investigas. Este hábito de predecir antes de medir es lo que separa al analista que presenta errores del que los atrapa antes de salir de su mesa.
### 2. Tendencia frente a historia: ¿se parece a los meses anteriores?
Un número no vive aislado. Tiene un pasado. Si las ventas de tu empresa llevan doce meses entre 3,8 y 4,5 millones, y de repente tu informe dice 7,2 millones, algo ha cambiado. Puede ser real (una campaña de Black Friday, la entrada en un mercado nuevo), pero si no hay una causa conocida que lo explique, el número merece investigación antes de presentarlo.
La comprobación es tan sencilla como añadir un WHERE que traiga los tres o cuatro meses anteriores y mirar si tu mes actual está en línea. Si hay un salto brutal y no sabes por qué, no lo presentes hasta saberlo. La peor situación posible es decir "hemos crecido un 80%" en una reunión y que alguien descubra al día siguiente que un duplicado infló la cifra.
### 3. Los totales cuadran: ¿la suma de las partes da el total?
Si desglosas ventas por canal y la suma de todos los canales no da el total general, hay un filtro escondido. Si desglosas usuarios por país y la suma no da el total de usuarios, hay filas sin país asignado que se están perdiendo. Este check es tan simple como sumar la columna de tu desglose y compararla con el total que reportas arriba.
Es especialmente importante cuando presentas un gráfico de tarta o un desglose porcentual. Si tus porcentajes suman 97% en vez de 100%, el director lo va a ver. Y la explicación "es que hay un 3% de filas sin categoría" no es una explicación: es un error que debiste detectar y decidir cómo tratar antes de presentar.
### 4. Nulos y ceros sospechosos
Un NULL en la columna de email puede ser normal: el usuario se registró con Google y no puso correo. Un NULL en la columna de importe de un pedido completado no es normal: algo falló en el registro. Un cero en "número de sesiones del mes" puede ser correcto (el usuario no entró). Un cero en "precio del producto" es sospechoso: alguien dejó el campo vacío y el sistema puso 0 por defecto.
La comprobación es: ¿hay NULLs o ceros en columnas donde no debería haberlos? Una query rápida con COUNT(*) - COUNT(columna) te dice cuántos NULLs hay. Si el número es cero o es bajo y esperado, adelante. Si de repente un 15% de tus importes son NULL, algo se rompió en el pipeline y tu total está subestimado.
### 5. Duplicados: ¿la misma fila aparece dos veces?
Este es el error silencioso por excelencia. Un JOIN mal hecho puede duplicar filas sin que tu query dé un error. Si la tabla de pedidos tiene 10.000 filas y después de hacer un JOIN con la tabla de productos tu resultado tiene 12.300 filas, esas 2.300 extra son duplicados creados por la relación uno-a-muchos. Tu SUM(importe) está inflado, nadie te ha avisado, y no puedes saber cuánto sin mirar: los pedidos que más se duplican son los que tienen más líneas, que suelen ser también los más grandes.
La comprobación mínima: cuenta las filas antes y después de cada JOIN. Si el número sube, tienes duplicados. La comprobación completa: busca filas idénticas con COUNT(*) GROUP BY las columnas clave HAVING COUNT(*) > 1. En datos de negocio, un pedido con el mismo id, la misma fecha y el mismo importe apareciendo dos veces no es una coincidencia: es un duplicado.
Los JOINs son la fuente número uno de duplicados invisibles. Si haces un LEFT JOIN de pedidos contra lineas_pedido (un pedido puede tener varias líneas), tu tabla resultante tiene MÁS filas que la original. Si después haces SUM(importe_pedido), estás sumando el importe del pedido una vez por cada línea. Un pedido de 100 EUR con tres líneas te da 300 EUR. El error es sutil, no da fallo, y puede multiplicar tu cifra sin que te des cuenta: basta con que los pedidos tengan varias líneas para que cada uno cuente tantas veces como líneas tenga.
### 6. Coherencia de fechas
¿Hay datos del futuro? Si hoy es 15 de julio y tu tabla tiene registros del 22 de julio, algo está mal. ¿Hay datos del 30 de febrero? Imposible, pero he visto sistemas que los generan al parsear mal una cadena de texto. ¿Hay datos de 1970? Eso es un timestamp sin inicializar (la epoch de Unix). ¿Hay datos anteriores a la fundación de la empresa? Entonces alguien cargó datos de prueba que no se borraron.
La comprobación: SELECT MIN(fecha), MAX(fecha) FROM tu_tabla. Si el mínimo o el máximo no tienen sentido, hay filas contaminadas. Este check tarda un segundo y atrapa errores que pasan meses sin que nadie los detecte, porque se esconden dentro de un agregado que "parece razonable".
### 7. El "olor" del número: ¿puedes explicarlo con una frase?
Este es el único check que no tiene una query. Es una pregunta que te haces a ti mismo: ¿puedo explicar este número con una frase sencilla? "Las ventas de junio fueron 4,1 millones, un 5% más que mayo, porque lanzamos la campaña de verano." Si puedes decir eso, el número tiene sentido. Si te sale 4,1 millones y no sabes por qué es más o menos que el mes anterior, todavía no lo entiendes.
Un número que no puedes explicar es un número que no deberías presentar. No porque esté mal: puede estar perfectamente bien. Pero si alguien te pregunta "¿por qué?" y no tienes respuesta, tu credibilidad se evapora. El check del "olor" es tu último filtro: si el número huele raro y no sabes por qué, investigas. Si huele bien y puedes explicarlo, lo presentas con confianza.
### Cómo implementarlos en SQL
Cada sanity check se traduce en una query rápida que puedes ejecutar en segundos. No son queries de producción ni informes elaborados: son preguntas directas a la base de datos que te dicen si algo huele mal. Vamos a ver las más importantes.
1-- CHECK 1: Orden de magnitud (comparar con el mes anterior)2SELECT3 DATE_TRUNC('month', fecha) AS mes,4 SUM(importe) AS total5FROM ventas6WHERE fecha >= CURRENT_DATE - INTERVAL '60 days'7GROUP BY 18ORDER BY 1;910-- CHECK 3: Totales que cuadran11SELECT12 SUM(importe) AS total_general,13 SUM(CASE WHEN canal = 'web' THEN importe END) AS web,14 SUM(CASE WHEN canal = 'app' THEN importe END) AS app,15 SUM(CASE WHEN canal = 'tienda' THEN importe END) AS tienda,16 -- Si esta suma no da total_general, hay filas sin canal17 COALESCE(SUM(CASE WHEN canal = 'web' THEN importe END), 0)18 + COALESCE(SUM(CASE WHEN canal = 'app' THEN importe END), 0)19 + COALESCE(SUM(CASE WHEN canal = 'tienda' THEN importe END), 0) AS suma_canales20FROM ventas21WHERE fecha BETWEEN '2024-06-01' AND '2024-06-30';
Queries de validación rápida: orden de magnitud y totales que cuadran
1-- CHECK 4: Nulos y ceros sospechosos2SELECT3 COUNT(*) AS total_filas,4 COUNT(*) - COUNT(importe) AS importes_null,5 COUNT(CASE WHEN importe = 0 THEN 1 END) AS importes_cero,6 COUNT(*) - COUNT(cliente_id) AS clientes_null7FROM pedidos8WHERE fecha BETWEEN '2024-06-01' AND '2024-06-30';910-- CHECK 5: Duplicados11SELECT12 pedido_id, fecha, importe,13 COUNT(*) AS veces14FROM pedidos15GROUP BY pedido_id, fecha, importe16HAVING COUNT(*) > 1;1718-- CHECK 6: Fechas imposibles19SELECT20 MIN(fecha) AS fecha_minima,21 MAX(fecha) AS fecha_maxima,22 COUNT(CASE WHEN fecha > CURRENT_DATE THEN 1 END) AS filas_futuro,23 COUNT(CASE WHEN fecha < '2015-01-01' THEN 1 END) AS filas_antes_empresa24FROM pedidos;
Queries de validación: nulos, duplicados y fechas imposibles
Consejo de senior: guarda estas queries en un fichero que puedas ejecutar antes de cualquier entrega. Yo tengo un script llamado "pre-entrega.sql" que corro en veinte segundos antes de cada informe. Cambia la tabla y las fechas, pero la estructura es siempre la misma. Es mi ritual. Y el día que me ahorro un ridículo en una reunión compensa con creces los mil días que no encontró nada.
### Cuándo hacerlos: SIEMPRE
No hay una excepción válida. "Pero es que la reunión es en diez minutos." Entonces hazlos en dos minutos: orden de magnitud y totales que cuadran. "Pero es que ya ejecuté esta query mil veces." Eso no significa que la tabla no haya cambiado desde la última vez. "Pero es que confío en el pipeline." Los pipelines se rompen. Se rompen en silencio, un martes cualquiera, y lo que te entregan parece perfecto hasta que comparas con el mes anterior.
La historia de la NASA no es un caso aislado exótico. Es la versión extrema de algo que pasa todos los días: un profesional competente asumió que el dato era correcto porque siempre lo había sido, y no lo comprobó. La diferencia entre perder una sonda y perder la confianza de tu equipo es de grado, no de clase. La causa es la misma: saltarse la comprobación porque "seguro que está bien".
### El caso de la NASA: cuando un sanity check habría salvado 327 millones
Volvamos al Mars Climate Orbiter. El software de navegación del equipo de Lockheed Martin calculaba el empuje en libras-fuerza (unidades imperiales). El equipo del JPL (Jet Propulsion Laboratory) de la NASA esperaba recibirlo en newtons (unidades métricas). La diferencia es un factor de 4,45. Durante nueve meses de viaje, nadie miró la trayectoria y dijo "esto no parece correcto". Las correcciones de rumbo iban acumulando un error que, al llegar a Marte, hizo que la sonda entrara 170 km más bajo de lo previsto.
Un sanity check de orden de magnitud lo habría atrapado. Si un ingeniero hubiera comparado el empuje calculado con el empuje esperado según el diseño de la sonda, habría visto que los números eran 4,45 veces más pequeños de lo que debían ser. No hace falta entender termodinámica para detectar que un número es cinco veces menor de lo esperado. Solo hace falta comparar.
La lección no es "la NASA comete errores". La lección es: cuando confías ciegamente en que el dato que recibes es correcto, asumes un riesgo proporcional a lo que está en juego. Para la NASA eran 327 millones de dólares. Para ti es la confianza de un equipo directivo que decide si te piden el próximo análisis a ti o a una consultora.
### Un ejemplo guiado completo
Te han pedido el informe de ventas de junio. Tu query da 3.840.000 EUR. Antes de ponerlo en la presentación, pasas tu checklist:
1-- 1. ORDEN DE MAGNITUD: mayo fue 3.600.000. Junio 3.840.000. +6,7%. Razonable.23-- 2. TENDENCIA: últimos 4 meses4-- Marzo: 3.500.000 | Abril: 3.550.000 | Mayo: 3.600.000 | Junio: 3.840.0005-- Tendencia creciente consistente. OK.67-- 3. TOTALES: desglose por canal8-- Web: 2.100.000 + App: 1.200.000 + Tienda: 540.000 = 3.840.000. Cuadra.910-- 4. NULOS11SELECT COUNT(*) - COUNT(importe) AS importes_null12FROM ventas WHERE fecha BETWEEN '2024-06-01' AND '2024-06-30';13-- Resultado: 0 nulos. OK.1415-- 5. DUPLICADOS16SELECT pedido_id, COUNT(*) FROM ventas17WHERE fecha BETWEEN '2024-06-01' AND '2024-06-30'18GROUP BY pedido_id HAVING COUNT(*) > 1;19-- Resultado: 0 filas. No hay duplicados. OK.2021-- 6. FECHAS22SELECT MIN(fecha), MAX(fecha) FROM ventas23WHERE fecha BETWEEN '2024-06-01' AND '2024-06-30';24-- Min: 2024-06-01, Max: 2024-06-30. Sin datos del futuro ni del pasado. OK.2526-- 7. OLOR: "Ventas de junio 3,84M, +6,7% sobre mayo, impulsado por27-- la campaña de verano que arrancó el día 10." Tiene sentido.
El checklist completo aplicado a un informe real: siete comprobaciones en menos de tres minutos
### Esto te lo van a preguntar en la entrevista
Una pregunta clásica en entrevistas técnicas para analista es: "¿Antes de entregar un informe, qué comprobaciones haces?" O su variante: "Tu query te da un resultado que parece demasiado bueno. ¿Qué haces?" La respuesta que esperan es sistemática, no "lo miro por encima". Quieren oír que tienes un checklist, que lo aplicas siempre, y que sabes distinguir entre un resultado real y uno contaminado por un error de datos.
### Resumen
- Un sanity check es una comprobación rápida de que tu número tiene sentido. No es una auditoría: es oler el plato antes de servirlo.
- Los siete checks son: orden de magnitud, tendencia frente a historia, totales que cuadran, nulos y ceros, duplicados, coherencia de fechas, y el "olor" del número.
- Se hacen SIEMPRE, antes de cada entrega, sin excepción. Tardan entre 30 segundos y 5 minutos.
- Cada check se implementa con una query SQL rápida que puedes guardar en un script reutilizable.
- Si un check no pasa, no presentas: investigas. Puede ser un error de datos (lo corriges) o un cambio real (lo documentas y explicas).
- El caso de la NASA recuerda que el coste de no comprobar es siempre mayor que el coste de comprobar.
Regístrate para guardar tu progreso.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...