NULLIF

La función NULLIF hace lo contrario de lo que podrías esperar por su nombre: en lugar de manejar valores NULL, los genera. Compara dos expresiones y, si son iguales, devuelve NULL. Si son diferentes, devuelve la primera expresión. Puede parecer un comportamiento extraño a primera vista, pero tiene aplicaciones muy prácticas, especialmente para evitar divisiones por cero y para limpiar valores centinela en los datos.

Sintaxis

NULLIF(expresion1, expresion2)

MySQL compara las dos expresiones. Si expresion1 = expresion2 es verdadero, devuelve NULL. Si son diferentes, devuelve expresion1. Es equivalente a escribir CASE WHEN expresion1 = expresion2 THEN NULL ELSE expresion1 END, pero de forma mucho más compacta.

Comportamiento básico

Para entender el funcionamiento, observa estos ejemplos directos:

SELECT
    NULLIF(10, 10)      AS iguales,
    NULLIF(10, 20)      AS diferentes,
    NULLIF('abc', 'abc') AS texto_igual,
    NULLIF('abc', 'xyz') AS texto_diff;
igualesdiferentestexto_igualtexto_diff
NULL10NULLabc

Cuando los dos valores coinciden, el resultado es NULL. Cuando difieren, se devuelve el primer valor sin modificar. Este comportamiento es la base de todos los usos prácticos de NULLIF.

Un caso habitual es detectar valores que deberían tratarse como ausentes. En muchas bases de datos heredadas, se usaba el valor 0 o una cadena vacía para indicar "sin dato" en lugar de NULL. Con NULLIF puedes convertir esos valores centinela en nulos reales:

SELECT
    nombre,
    telefono_secundario,
    NULLIF(telefono_secundario, '') AS telefono_limpio
FROM clientes
LIMIT 4;
nombretelefono_secundariotelefono_limpio
MaríaNULL
Carlos612345678612345678
AnaNULL
Pedro698765432698765432

Si telefono_secundario contiene una cadena vacía, NULLIF la convierte en NULL. Si contiene un número real, lo devuelve tal cual. Una vez convertido a NULL, puedes aplicar funciones como IFNULL o COALESCE para asignar un valor por defecto.

Caso práctico: prevenir la división por cero

Este es el uso más conocido y probablemente el más importante de NULLIF. En MySQL, dividir entre cero no produce un error sino que devuelve NULL, pero en algunos contextos puede provocar advertencias o resultados inesperados. Con NULLIF puedes proteger tus divisiones de forma elegante:

SELECT
    nombre,
    ingresos,
    gastos,
    ROUND(ingresos / NULLIF(gastos, 0), 2) AS ratio_ing_gas
FROM departamentos;
nombreingresosgastosratio_ing_gas
Ventas450000.00120000.003.75
Marketing280000.0095000.002.95
Soporte0.0085000.000.00
Innovación50000.000.00NULL

NULLIF(gastos, 0) devuelve NULL cuando los gastos son cero, lo que hace que la división ingresos / NULL produzca NULL en lugar de un resultado incorrecto o una advertencia. Cuando los gastos tienen un valor real, NULLIF los devuelve sin cambios y la división se ejecuta normalmente.

Este patrón es especialmente útil en reportes de porcentaje donde el denominador puede ser cero:

SELECT
    c.nombre AS categoria,
    COUNT(p.id) AS total_productos,
    SUM(CASE WHEN p.stock = 0 THEN 1 ELSE 0 END) AS agotados,
    ROUND(
        SUM(CASE WHEN p.stock = 0 THEN 1 ELSE 0 END) * 100.0
        / NULLIF(COUNT(p.id), 0),
        1
    ) AS pct_agotados
FROM categorias c
LEFT JOIN productos p ON c.id = p.categoria_id
GROUP BY c.id, c.nombre
ORDER BY pct_agotados DESC;
categoriatotal_productosagotadospct_agotados
Smartphones400.0
Portátiles300.0
Ropa400.0
Hogar400.0
Deportes300.0
Libros00NULL

Las categorías sin productos (como Libros en este ejemplo) tienen un COUNT de 0. Sin NULLIF, la división entre cero produciría un resultado confuso. Con NULLIF, esas categorías muestran NULL en el porcentaje, lo que indica claramente que el cálculo no es aplicable.

Caso práctico: limpiar valores centinela para funciones de agregación

Algunas aplicaciones almacenan 0 o -1 como valor centinela en lugar de NULL. Esto distorsiona las funciones de agregación como AVG o MIN. NULLIF permite neutralizar esos valores:

SELECT
    puesto,
    COUNT(*) AS empleados,
    ROUND(AVG(salario), 2) AS media_con_ceros,
    ROUND(AVG(NULLIF(salario, 0)), 2) AS media_real
FROM empleados
GROUP BY puesto;
puestoempleadosmedia_con_cerosmedia_real
Director155000.0055000.00
Jefe de equipo245000.0045000.00
Desarrollador235000.0035000.00
Vendedor216000.0032000.00

En el puesto de Vendedor, hay un registro con salario 0 (quizá un becario o un error de datos). AVG(salario) incluye ese cero en el cálculo, lo que reduce la media artificialmente. AVG(NULLIF(salario, 0)) convierte los ceros en NULL, y como AVG ignora los nulos, calcula la media solo con los valores reales.

Este mismo patrón funciona con SUM, MIN y cualquier otra función de agregación. Es una técnica esencial cuando trabajas con datos importados de sistemas externos que no usan NULL de forma estándar.

Caso práctico: lógica inversa con IFNULL

NULLIF y IFNULL son funciones complementarias que se combinan con frecuencia. NULLIF genera nulos cuando encuentra un valor específico, e IFNULL los reemplaza por otro. Juntas, permiten sustituir un valor concreto por otro:

SELECT
    nombre,
    estado,
    IFNULL(NULLIF(estado, 'cancelado'), 'Requiere nueva orden') AS accion
FROM pedidos
LIMIT 6;
nombreestadoaccion
Maríaentregadoentregado
Carlosentregadoentregado
Anaenviadoenviado
PedrocanceladoRequiere nueva orden
Lucíapendientependiente
JaviercanceladoRequiere nueva orden

NULLIF(estado, 'cancelado') convierte los estados 'cancelado' en NULL. Luego IFNULL(..., 'Requiere nueva orden') sustituye esos NULL por el mensaje de acción. El resultado final es que los pedidos cancelados muestran un texto de acción, mientras que los demás estados se mantienen sin cambios.

Manejo de NULL

Cuando alguno de los argumentos de NULLIF ya es NULL, el comportamiento sigue la regla de comparación de MySQL: NULL = NULL no es verdadero (es NULL), por lo que NULLIF(NULL, NULL) devuelve NULL pero no porque los valores sean iguales, sino porque el primer argumento ya es NULL:

SELECT
    NULLIF(NULL, NULL)  AS ambos_null,
    NULLIF(NULL, 10)    AS primero_null,
    NULLIF(10, NULL)    AS segundo_null;
ambos_nullprimero_nullsegundo_null
NULLNULL10

En la práctica, NULLIF rara vez recibe NULL como primer argumento, ya que su propósito principal es convertir valores específicos en NULL, no procesar nulos existentes. Si necesitas comprobar si un valor ya es NULL, usa IS NULL, IFNULL o COALESCE.

Combinación con otras funciones

NULLIF se combina especialmente bien con CONCAT para evitar cadenas vacías en concatenaciones:

SELECT
    nombre,
    apellidos,
    CONCAT(
        nombre,
        IFNULL(CONCAT(' ', NULLIF(segundo_nombre, '')), ''),
        ' ',
        apellidos
    ) AS nombre_completo
FROM clientes
LIMIT 4;
nombreapellidosnombre_completo
MaríaGarcía LópezMaría García López
CarlosRodríguez MartínCarlos Alberto Rodríguez Martín
AnaMartínez RuizAna Martínez Ruiz
PedroFernández CastroPedro José Fernández Castro

NULLIF(segundo_nombre, '') convierte los nombres vacíos en NULL. Luego CONCAT(' ', NULL) devuelve NULL, e IFNULL(..., '') convierte ese NULL en una cadena vacía para que no afecte a la concatenación exterior. El resultado es un nombre completo limpio, con o sin segundo nombre, sin espacios dobles ni huecos.

También es habitual combinar NULLIF con ROUND y operaciones de porcentaje en reportes financieros:

SELECT
    nombre,
    ventas_actual,
    ventas_anterior,
    ROUND(
        (ventas_actual - ventas_anterior)
        / NULLIF(ventas_anterior, 0) * 100,
        1
    ) AS variacion_pct
FROM departamentos;
nombreventas_actualventas_anteriorvariacion_pct
Ventas45000038000018.4
Marketing280000310000-9.7
Soporte95000950000.0
Innovación500000NULL

El departamento de Innovación no tenía ventas el periodo anterior, así que NULLIF convierte el cero en NULL y el resultado es NULL en lugar de un infinito o un error. Los demás departamentos muestran su variación porcentual correctamente.

Practica con NULLIF

Usa el editor para convertir valores específicos en NULL con NULLIF:

Simulador SQL
Ctrl+Enter para ejecutar

En el siguiente artículo veremos COALESCE para elegir el primer valor no nulo de una lista.

Escrito por Eduardo Lázaro