IFNULL
La función IFNULL resuelve uno de los problemas más comunes al trabajar con bases de datos: los valores NULL. Cuando una columna contiene NULL, cualquier operación aritmética o concatenación con ese valor produce NULL como resultado, lo que puede arruinar cálculos, reportes y visualizaciones. IFNULL permite sustituir esos nulos por un valor alternativo de forma rápida y legible.
Sintaxis
IFNULL(expresion, valor_alternativo)MySQL evalúa la primera expresión. Si no es NULL, la devuelve tal cual. Si es NULL, devuelve el segundo argumento. Es una forma abreviada de escribir CASE WHEN expresion IS NOT NULL THEN expresion ELSE valor_alternativo END, pero mucho más concisa.
Comportamiento básico
Supón que la tabla clientes tiene una columna telefono_secundario que puede ser NULL cuando el cliente no proporcionó un número alternativo:
SELECT
nombre,
apellidos,
telefono,
telefono_secundario,
IFNULL(telefono_secundario, 'No proporcionado') AS contacto_alt
FROM clientes
LIMIT 6;| nombre | apellidos | telefono | telefono_secundario | contacto_alt |
|---|---|---|---|---|
| María | García López | 611223344 | NULL | No proporcionado |
| Carlos | Rodríguez Martín | 622334455 | 612345678 | 612345678 |
| Ana | Martínez Ruiz | 633445566 | NULL | No proporcionado |
| Pedro | Fernández Castro | 644556677 | 698765432 | 698765432 |
| Lucía | Sánchez Moreno | 655667788 | NULL | No proporcionado |
| Javier | López García | 666778899 | 678901234 | 678901234 |
Cuando telefono_secundario tiene un valor, IFNULL lo devuelve sin modificarlo. Cuando es NULL, devuelve la cadena 'No proporcionado'. El resultado es una columna limpia, sin valores nulos, lista para mostrar en un informe o en la interfaz de una aplicación.
Con valores numéricos funciona igual. Para mostrar descuentos aplicados, donde NULL significa que no hay descuento:
SELECT
nombre,
precio,
IFNULL(descuento, 0) AS descuento_aplicado,
precio * (1 - IFNULL(descuento, 0) / 100) AS precio_final
FROM productos
LIMIT 5;| nombre | precio | descuento_aplicado | precio_final |
|---|---|---|---|
| iPhone 15 Pro | 1299.99 | 0 | 1299.99 |
| Samsung Galaxy S24 | 899.99 | 10 | 809.99 |
| Google Pixel 8 | 699.00 | 0 | 699.00 |
| Xiaomi 14 | 599.99 | 15 | 509.99 |
| MacBook Air M3 | 1399.00 | 0 | 1399.00 |
Sin IFNULL, la expresión precio * (1 - NULL / 100) devolvería NULL para cualquier producto sin descuento, porque la aritmética con NULL siempre propaga NULL. Al sustituir el nulo por 0, el cálculo funciona correctamente.
Caso práctico: evitar propagación de NULL en cálculos
Este es probablemente el uso más importante de IFNULL. Imagina que calculas el margen de beneficio de cada producto, pero la columna coste puede ser NULL para productos recién añadidos al catálogo cuyo coste aún no se ha registrado:
SELECT
nombre,
precio,
coste,
precio - IFNULL(coste, 0) AS margen_bruto,
ROUND((precio - IFNULL(coste, 0)) / precio * 100, 1) AS margen_pct
FROM productos
WHERE categoria_id = 6;| nombre | precio | coste | margen_bruto | margen_pct |
|---|---|---|---|---|
| iPhone 15 Pro | 1299.99 | 850.00 | 449.99 | 34.6 |
| Samsung Galaxy S24 | 899.99 | 580.00 | 319.99 | 35.6 |
| Google Pixel 8 | 699.00 | NULL | 699.00 | 100.0 |
| Xiaomi 14 | 599.99 | 390.00 | 209.99 | 35.0 |
Sin IFNULL(coste, 0), las filas donde coste es NULL producirían NULL tanto en margen_bruto como en margen_pct. El reporte tendría huecos que dificultan el análisis. Con IFNULL, esas filas muestran el precio completo como margen, lo que al menos permite seguir trabajando con los datos. Por supuesto, un margen del 100% indica que falta el coste, algo que el equipo de compras debería corregir.
Caso práctico: resultados de LEFT JOIN
Cuando haces un LEFT JOIN, las columnas de la tabla derecha contienen NULL para las filas de la tabla izquierda que no tienen correspondencia. IFNULL es especialmente útil aquí para limpiar el resultado:
SELECT
c.nombre,
c.apellidos,
IFNULL(COUNT(p.id), 0) AS total_pedidos,
IFNULL(SUM(p.total), 0) AS importe_total,
IFNULL(MAX(p.fecha_pedido), 'Sin pedidos') AS ultimo_pedido
FROM clientes c
LEFT JOIN pedidos p ON c.id = p.cliente_id
GROUP BY c.id, c.nombre, c.apellidos
ORDER BY importe_total DESC
LIMIT 8;| nombre | apellidos | total_pedidos | importe_total | ultimo_pedido |
|---|---|---|---|---|
| Pedro | Fernández Castro | 3 | 2228.97 | 2025-12-05 11:15:00 |
| Carlos | Rodríguez Martín | 2 | 1949.98 | 2025-10-22 18:10:00 |
| María | García López | 2 | 1349.98 | 2025-10-15 09:30:00 |
| Ana | Martínez Ruiz | 1 | 1899.99 | 2025-10-25 16:45:00 |
| Lucía | Sánchez Moreno | 1 | 549.00 | 2025-11-01 09:15:00 |
| Isabel | Muñoz Pérez | 1 | 329.98 | 2025-12-15 10:00:00 |
| Sandra | Blanco Calvo | 0 | 0 | Sin pedidos |
| Fernando | Díaz Navarro | 0 | 0 | Sin pedidos |
Los clientes que nunca han realizado un pedido tendrían NULL en las columnas de agregación sin IFNULL. En su lugar, vemos 0 en el conteo y el importe, y un mensaje descriptivo en la fecha. Este tipo de limpieza es esencial cuando los datos se consumen desde una aplicación o se exportan a un informe.
Caso práctico: valores por defecto en formularios
Al insertar datos desde formularios web, es habitual que algunos campos opcionales lleguen como NULL. Puedes usar IFNULL al consultar esos datos para proporcionar valores por defecto:
SELECT
c.nombre,
IFNULL(p.direccion_envio, c.direccion) AS direccion_entrega,
IFNULL(p.notas, 'Sin instrucciones especiales') AS instrucciones
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.id
LIMIT 4;| nombre | direccion_entrega | instrucciones |
|---|---|---|
| María | Calle Mayor 15, Madrid | Dejar en portería |
| Carlos | Av. Diagonal 250, Barcelona | Sin instrucciones especiales |
| Ana | Gran Vía 42, Madrid | Llamar antes de entregar |
| Pedro | Calle Sierpes 8, Sevilla | Sin instrucciones especiales |
Si el cliente proporcionó una dirección de envío diferente, se usa esa. Si no, se recurre a la dirección del cliente. Este patrón de "cascada" es muy común. Para más de dos opciones, la función COALESCE ofrece la misma funcionalidad con cualquier número de argumentos.
Manejo de NULL
Es importante entender qué IFNULL considera como NULL y qué no. La función solo sustituye valores estrictamente NULL. Las cadenas vacías (''), los ceros (0) y los espacios en blanco (' ') no son NULL y no serán reemplazados:
SELECT
IFNULL(NULL, 'es nulo') AS prueba1,
IFNULL('', 'es nulo') AS prueba2,
IFNULL(0, 'es nulo') AS prueba3,
IFNULL('texto', 'es nulo') AS prueba4;| prueba1 | prueba2 | prueba3 | prueba4 |
|---|---|---|---|
| es nulo | 0 | texto |
Solo la primera prueba devuelve el valor alternativo, porque es la única que recibe un NULL real. La cadena vacía, el cero y el texto normal se devuelven tal cual. Si necesitas tratar las cadenas vacías como nulas, puedes combinar IFNULL con NULLIF:
SELECT IFNULL(NULLIF(campo, ''), 'valor por defecto');NULLIF(campo, '') convierte las cadenas vacías en NULL, y luego IFNULL sustituye ese NULL por el valor por defecto. Esta combinación es un patrón frecuente para limpiar datos importados de fuentes externas.
Combinación con otras funciones
IFNULL se combina frecuentemente con funciones de agregación que pueden devolver NULL cuando no hay filas que procesar:
SELECT
c.nombre AS categoria,
IFNULL(AVG(p.precio), 0) AS precio_medio,
IFNULL(SUM(p.stock), 0) AS stock_total,
CONCAT(
IFNULL(COUNT(p.id), 0),
' productos'
) AS resumen
FROM categorias c
LEFT JOIN productos p ON c.id = p.categoria_id
GROUP BY c.id, c.nombre
ORDER BY stock_total DESC
LIMIT 6;| categoria | precio_medio | stock_total | resumen |
|---|---|---|---|
| Accesorios electrónicos | 35.32 | 650 | 3 productos |
| Ropa | 72.49 | 585 | 4 productos |
| Smartphones | 849.74 | 225 | 4 productos |
| Hogar | 416.25 | 143 | 4 productos |
| Deportes | 164.99 | 135 | 3 productos |
| Portátiles | 1615.99 | 55 | 3 productos |
AVG, SUM y COUNT devuelven NULL cuando se aplican a un conjunto vacío (por ejemplo, una categoría sin productos en un LEFT JOIN). Envolver estas funciones con IFNULL garantiza que el resultado siempre tenga valores numéricos válidos en lugar de espacios en blanco.
La diferencia entre IFNULL y COALESCE es que IFNULL acepta exactamente dos argumentos, mientras que COALESCE acepta cualquier número. Si necesitas comprobar más de dos posibles valores nulos en cascada, COALESCE es la mejor opción, como veremos más adelante.
Practica con IFNULL
Usa el editor para reemplazar valores nulos con IFNULL:
En el siguiente artículo veremos NULLIF para generar valores NULL condicionalmente.
Escrito por Eduardo Lázaro
