Error SQL · expresiones numéricas

División por cero en SQL: evita el error con NULLIF

Dividir entre cero no se comporta igual en todos los motores: algunos generan un error y otros devuelven NULL. La solución portable es decidir primero qué significa un denominador cero y proteger la expresión explícitamente.

Lectura: 12–16 minDiferencias por motorPráctica correctiva

Síntoma

Una expresión como importe / unidades funciona para muchas filas, pero falla o devuelve NULL cuando unidades = 0. No intentes ocultar la situación con un valor arbitrario: primero define qué debe representar matemáticamente y en el negocio.

El comportamiento cambia según el motor

MotorComportamiento relevante
PostgreSQLLa división por cero corresponde al error SQLSTATE 22012 (division_by_zero).
SQL ServerCon ANSI_WARNINGS ON, una división por cero genera error; la configuración puede alterar ese comportamiento.
MySQL 8.4En un SELECT, la división por cero devuelve NULL; los modos SQL influyen en advertencias y operaciones de escritura.
SQLiteDocumenta que la división por cero devuelve NULL.

Por eso no conviene aprender «SQL siempre falla» ni «SQL siempre devuelve NULL». Es una diferencia de motor y configuración que debes tratar de forma deliberada.

Patrón seguro: NULLIF(denominador, 0)

NULLIF(x, 0) devuelve NULL cuando x vale cero. Dividir por NULL produce NULL en lugar de intentar una división matemática inválida. Así expresas que la razón no puede calcularse para esa fila.

Proteger el denominador
WITH metricas(nombre, importe, unidades) AS (
  VALUES ('A', 120.0, 4), ('B', 75.0, 0), ('C', 90.0, 3)
)
SELECT
  nombre,
  importe / NULLIF(unidades, 0) AS importe_por_unidad
FROM metricas
ORDER BY nombre;
Resultado comprobado en SQLite 3.46.1
nombreimporte_por_unidad
A30.0
BNULL
C30.0

¿Y si necesitas mostrar cero?

Puedes envolver la expresión con COALESCE(..., 0), pero solo si cero es el significado correcto. «No se puede calcular una razón porque no hay unidades» no siempre equivale a «la razón es cero».

COALESCE(importe / NULLIF(unidades, 0), 0)

Ese patrón cambia un valor desconocido/no calculable por un cero explícito. Úsalo como decisión de negocio, no como parche técnico automático.

CASE también sirve cuando necesitas distinguir casos

Si un denominador cero necesita una etiqueta, una regla distinta o un cálculo alternativo, CASE comunica mejor la decisión:

CASE
  WHEN unidades = 0 THEN NULL
  ELSE importe / unidades
END AS importe_por_unidad

No cambies el denominador 0 por 1 solo para evitar el error. Eso fabrica un cociente diferente y puede producir métricas engañosas.

Práctica: tasa de conversión

Básica · expresiones y NULL

Calcula una tasa sin dividir por cero

Devuelve la tasa compras / visitas para cada campaña. Cuando visitas sea 0, el resultado debe ser NULL.

Qué debes recordar

  • La división por cero no tiene un comportamiento idéntico en todos los motores.
  • NULLIF(denominador, 0) evita intentar la división y produce un resultado nulo.
  • COALESCE(..., 0) solo es correcto si cero representa realmente el caso de negocio.
  • CASE es preferible cuando necesitas una política especial para el denominador cero.

Conceptos relacionados

Fuentes técnicas consultadas