COALESCE

La función COALESCE recorre una lista de expresiones de izquierda a derecha y devuelve la primera que no sea NULL. Si todas son NULL, devuelve NULL. Es la versión generalizada de IFNULL: mientras que IFNULL acepta exactamente dos argumentos, COALESCE acepta cualquier número, lo que la convierte en la herramienta ideal para establecer cadenas de valores de respaldo.

Además, COALESCE forma parte del estándar ANSI SQL, por lo que funciona de la misma manera en MySQL, PostgreSQL, SQL Server y Oracle. Si escribes consultas que pueden ejecutarse en diferentes motores de base de datos, COALESCE es la opción más portable.

Sintaxis

COALESCE(expresion1, expresion2, ..., expresionN)

MySQL evalúa las expresiones en orden, de izquierda a derecha. En cuanto encuentra una que no es NULL, la devuelve y deja de evaluar las restantes. Esto significa que las expresiones más probables de tener valor deberían ir primero por eficiencia, aunque en la práctica la diferencia de rendimiento es insignificante.

Comportamiento básico

Para entender cómo funciona la evaluación en cascada:

SELECT
    COALESCE(NULL, NULL, 'tercero')     AS ejemplo1,
    COALESCE(NULL, 'segundo', 'tercero') AS ejemplo2,
    COALESCE('primero', 'segundo')       AS ejemplo3,
    COALESCE(NULL, NULL, NULL)           AS ejemplo4;
ejemplo1ejemplo2ejemplo3ejemplo4
tercerosegundoprimeroNULL

En el primer caso, las dos primeras expresiones son NULL, así que devuelve la tercera. En el segundo, la primera es NULL pero la segunda tiene valor, y se devuelve directamente. En el tercero, la primera expresión ya tiene valor, así que ni siquiera se evalúa la segunda. En el cuarto, todas son NULL, y el resultado es NULL.

Un uso inmediato es proporcionar valores por defecto al mostrar datos de una tabla:

SELECT
    nombre,
    COALESCE(telefono_secundario, telefono, 'Sin contacto') AS mejor_telefono
FROM clientes
LIMIT 6;
nombremejor_telefono
María611223344
Carlos612345678
Ana633445566
Pedro698765432
Lucía655667788
Javier678901234

Para cada cliente, MySQL intenta primero el teléfono secundario. Si es NULL, usa el teléfono principal. Si ambos fueran NULL (algo improbable pero posible), mostraría el texto 'Sin contacto'. Con IFNULL necesitarías anidar dos llamadas para lograr lo mismo: IFNULL(telefono_secundario, IFNULL(telefono, 'Sin contacto')).

Caso práctico: cadena de contacto de respaldo

En sistemas de atención al cliente es habitual tener múltiples canales de contacto, pero no todos los clientes proporcionan todos. COALESCE permite seleccionar el mejor canal disponible:

SELECT
    nombre,
    apellidos,
    COALESCE(email_trabajo, email_personal, email_alternativo) AS email_contacto,
    COALESCE(telefono_movil, telefono_fijo, telefono_empresa) AS telefono_contacto
FROM clientes
LIMIT 6;
nombreapellidosemail_contactotelefono_contacto
MaríaGarcía Lópezmaria.garcia@empresa.com611223344
CarlosRodríguez Martíncarlos.rodriguez@email.com622334455
AnaMartínez Ruizana.martinez@trabajo.com633445566
PedroFernández Castropedro.fernandez@email.com698765432
LucíaSánchez Morenolucia.sanchez@email.com655667788
JavierLópez Garcíajavier@empresa.com678901234

La prioridad de contacto queda definida por el orden de los argumentos: primero el email de trabajo, luego el personal, y finalmente el alternativo. Si reorganizas los argumentos, cambias la prioridad. Esta es una forma declarativa y fácil de mantener para definir reglas de negocio de contacto.

Caso práctico: fusionar columnas de un JOIN

Cuando unes varias tablas que tienen columnas equivalentes, COALESCE permite fusionarlas en una sola columna coherente. Este patrón es especialmente común con FULL OUTER JOIN o múltiples LEFT JOIN:

SELECT
    COALESCE(p.nombre, d.nombre_pedido) AS producto,
    COALESCE(p.precio, d.precio_unitario) AS precio,
    d.cantidad,
    COALESCE(p.precio, d.precio_unitario) * d.cantidad AS subtotal
FROM detalle_pedidos d
LEFT JOIN productos p ON d.producto_id = p.id
WHERE d.pedido_id = 5
ORDER BY subtotal DESC;
productopreciocantidadsubtotal
ASUS ROG Zephyrus1899.9911899.99

Si un producto fue eliminado del catálogo pero su registro sigue en el detalle del pedido, p.nombre sería NULL porque el LEFT JOIN no encontraría coincidencia. COALESCE recurre entonces a d.nombre_pedido, un campo que almacena una copia del nombre en el momento de la compra. Este patrón garantiza que los reportes históricos nunca muestren datos vacíos, independientemente de los cambios en el catálogo.

Caso práctico: valores calculados con respaldo

COALESCE también funciona con expresiones calculadas, no solo con columnas directas. Esto es útil para construir métricas con niveles de precisión decrecientes:

SELECT
    nombre,
    precio,
    coste,
    margen_manual,
    COALESCE(
        margen_manual,
        precio - coste,
        precio * 0.30
    ) AS margen_estimado
FROM productos
WHERE categoria_id = 6;
nombrepreciocostemargen_manualmargen_estimado
iPhone 15 Pro1299.99850.00450.00450.00
Samsung Galaxy S24899.99580.00NULL319.99
Google Pixel 8699.00NULLNULL209.70
Xiaomi 14599.99390.00NULL209.99

La cadena de respaldo funciona así: primero se usa el margen registrado manualmente (si existe), luego se calcula a partir del precio y el coste (si ambos tienen valor), y finalmente se estima como el 30% del precio (si todo lo anterior es NULL). Cada nivel de respaldo ofrece menos precisión, pero garantiza que siempre haya un valor disponible para el análisis.

Manejo de NULL

COALESCE trata los valores NULL de forma transparente, pero hay un detalle sobre los tipos de datos que conviene conocer. Cuando mezclas tipos diferentes en los argumentos, MySQL determina el tipo del resultado basándose en todos los argumentos, no solo en el que devuelve:

SELECT
    COALESCE(NULL, NULL, 42)        AS numero,
    COALESCE(NULL, 'texto', 42)     AS mixto,
    COALESCE(NULL, NULL, NOW())     AS fecha;
numeromixtofecha
42texto2026-02-14 15:30:00

En el caso de mixto, aunque devuelve 'texto', MySQL considera que la columna podría contener también un número (42), así que ajusta el tipo internamente. En la práctica esto rara vez causa problemas, pero si necesitas un tipo específico en el resultado, puedes usar CAST para forzarlo:

SELECT COALESCE(CAST(campo_numerico AS CHAR), campo_texto, 'N/A') AS resultado;

Otro aspecto a tener en cuenta es que COALESCE con un solo argumento simplemente devuelve ese argumento (o NULL si es NULL). Aunque no tiene sentido práctico, es un comportamiento válido y no produce errores.

Combinación con otras funciones

COALESCE se combina frecuentemente con CONCAT para construir cadenas que incluyen datos opcionales:

SELECT
    CONCAT(
        nombre,
        ' ',
        apellidos,
        COALESCE(CONCAT(' (', apodo, ')'), '')
    ) AS nombre_display
FROM clientes
LIMIT 5;
nombre_display
María García López
Carlos Rodríguez Martín (Charlie)
Ana Martínez Ruiz
Pedro Fernández Castro (Pete)
Lucía Sánchez Moreno

Si el cliente tiene apodo, se muestra entre paréntesis. Si no, COALESCE devuelve una cadena vacía que no afecta al resultado. El truco está en que CONCAT(' (', NULL, ')') devuelve NULL (porque cualquier CONCAT con NULL produce NULL), y entonces COALESCE selecciona la cadena vacía alternativa.

También se usa con funciones de agregación en subconsultas para proporcionar valores por defecto:

SELECT
    c.nombre,
    c.apellidos,
    COALESCE(
        (SELECT SUM(p.total) FROM pedidos p WHERE p.cliente_id = c.id AND p.estado = 'entregado'),
        0
    ) AS total_comprado,
    COALESCE(
        (SELECT MAX(p.fecha_pedido) FROM pedidos p WHERE p.cliente_id = c.id),
        'Nunca'
    ) AS ultima_actividad
FROM clientes c
ORDER BY total_comprado DESC
LIMIT 6;
nombreapellidostotal_compradoultima_actividad
MaríaGarcía López1349.982025-10-15 09:30:00
CarlosRodríguez Martín1949.982025-10-22 18:10:00
AnaMartínez Ruiz1899.992025-10-25 16:45:00
PedroFernández Castro79.982025-12-05 11:15:00
SandraBlanco Calvo0Nunca
FernandoDíaz Navarro0Nunca

Las subconsultas devuelven NULL cuando no hay filas que cumplan la condición (por ejemplo, clientes sin pedidos entregados). COALESCE convierte esos NULL en valores legibles: 0 para los importes y 'Nunca' para las fechas.

En términos de portabilidad, COALESCE es siempre la opción recomendada sobre IFNULL cuando escribes SQL que podría ejecutarse en diferentes motores de base de datos. IFNULL es específica de MySQL, mientras que COALESCE es parte del estándar SQL y funciona en todos los sistemas relacionales principales.

Practica con COALESCE

Usa el editor para seleccionar el primer valor no nulo con COALESCE:

Simulador SQL
Ctrl+Enter para ejecutar

En el siguiente artículo veremos ISNULL para verificar si un valor es NULL.

Escrito por Eduardo Lázaro