CONCAT

La función CONCAT une dos o más cadenas en una sola. Es, junto con SUBSTRING, una de las funciones de cadena que más se usa en el día a día: aparece cada vez que necesitas componer un nombre completo a partir de varias columnas, construir un texto descriptivo, generar fragmentos de HTML o preparar una etiqueta para mostrar.

Su funcionamiento es sencillo, pero esconde un comportamiento que sorprende a mucha gente y que es la causa de errores muy comunes: si cualquiera de sus argumentos es NULL, el resultado completo es NULL. Entender esto, y saber cómo evitarlo, es la diferencia entre una concatenación robusta y una que devuelve valores vacíos sin explicación aparente. En este artículo veremos su sintaxis, la conversión automática de números, ese comportamiento con NULL y la confusión habitual con el operador ||.

Sintaxis

CONCAT acepta cualquier número de argumentos y los une en el orden en que se escriben. No añade ningún separador entre ellos.

CONCAT(cadena1, cadena2, ..., cadenaN)

Sus tres reglas de comportamiento más importantes son:

  • Acepta uno o más argumentos
  • Si cualquier argumento es NULL, el resultado es NULL
  • Convierte automáticamente los valores numéricos a cadena

Ejemplos básicos

En su uso más simple, une varias cadenas literales. Para que haya un espacio entre palabras, hay que incluirlo explícitamente como un argumento más:

SELECT CONCAT('Hola', ' ', 'mundo') AS saludo;
saludo
Hola mundo

Si alguno de los argumentos es un número, CONCAT lo convierte a texto de forma automática, sin necesidad de conversiones manuales:

SELECT CONCAT('MySQL', ' ', 8.0) AS version;
version
MySQL 8.0

Concatenar columnas

El uso real más frecuente es combinar columnas de una tabla con texto fijo, por ejemplo para mostrar un producto junto a su precio en una sola celda:

SELECT CONCAT(nombre, ' - $', precio) AS producto_precio
FROM productos
LIMIT 5;
producto_precio
iPhone 15 Pro - $1299.99
MacBook Air M2 - $1199.99
AirPods Pro - $249.99
iPad Air - $599.99
Apple Watch Series 9 - $399.99

Componer el nombre completo de una persona a partir de columnas separadas es otro caso clásico:

SELECT CONCAT(nombre, ' ', apellidos) AS nombre_completo, email
FROM clientes
LIMIT 5;
nombre_completoemail
María García Lópezmaria.garcia@email.com
Carlos Rodríguez Martíncarlos.rodriguez@email.com
Laura López Sánchezlaura.lopez@email.com
Pedro Fernández Castropedro.fernandez@email.com
Ana Martínez Ruizana.martinez@email.com

CONCAT con NULL

Aquí está el comportamiento que conviene tener siempre presente. Basta con que uno solo de los argumentos sea NULL para que toda la concatenación devuelva NULL, descartando el resto de valores:

SELECT CONCAT('Hola', NULL, 'mundo') AS resultado;
resultado
NULL

Para evitarlo, se envuelve la columna que pueda ser nula en IFNULL o COALESCE, que sustituyen el NULL por un texto alternativo antes de concatenar:

SELECT CONCAT('Stock: ', IFNULL(stock, 'Sin datos')) AS info
FROM productos
WHERE id = 1;
info
Stock: 50

Como alternativa, si lo que quieres es precisamente ignorar los valores nulos, CONCAT_WS los descarta automáticamente en lugar de propagarlos.

Concatenar en WHERE

CONCAT puede usarse dentro de un filtro para buscar en la combinación de varias columnas a la vez, junto con LIKE:

SELECT nombre, precio
FROM productos
WHERE CONCAT(nombre, ' ', precio) LIKE '%Pro%';
nombreprecio
iPhone 15 Pro1299.99
AirPods Pro249.99

Hay que ser consciente de que aplicar CONCAT en el WHERE impide usar índices sobre esas columnas, por lo que en tablas grandes esta técnica puede resultar lenta. Para búsquedas frecuentes conviene replantear el filtro o recurrir a un índice de texto completo.

Construir etiquetas HTML

Como CONCAT une texto sin más, sirve para envolver valores en fragmentos de marcado, por ejemplo para resaltar nombres en negrita:

SELECT CONCAT('<strong>', nombre, '</strong>') AS html
FROM categorias
LIMIT 3;
html
<strong>Electrónica</strong>
<strong>Accesorios electrónicos</strong>
<strong>Hogar inteligente</strong>

CONCAT frente a GROUP_CONCAT

Conviene no confundir CONCAT con GROUP_CONCAT. El primero une valores de una misma fila; el segundo es una función de agregación que une valores de varias filas en una sola cadena, lo que sirve, por ejemplo, para listar todos los productos de cada categoría:

SELECT c.nombre AS categoria,
       GROUP_CONCAT(p.nombre SEPARATOR ', ') AS productos
FROM categorias c
JOIN productos p ON c.id = p.categoria_id
GROUP BY c.id
LIMIT 3;

CONCAT frente al operador ||

En otros sistemas de bases de datos, el operador || concatena cadenas. En MySQL, por defecto, || significa el OR lógico, así que usarlo para concatenar da resultados inesperados. Solo se comporta como concatenación si activas el modo PIPES_AS_CONCAT:

-- Por defecto, || es OR lógico
SELECT 'Hola' || 'Mundo';
 
-- Para usarlo como concatenación hay que cambiar el sql_mode
SET sql_mode = 'PIPES_AS_CONCAT';
SELECT 'Hola' || ' ' || 'Mundo';

Para evitar ambigüedades y mantener la portabilidad del código, lo más recomendable es usar siempre CONCAT y no depender de ||.

Errores comunes

El error más extendido, con diferencia, es olvidar el comportamiento con NULL: un nombre completo que aparece vacío suele deberse a que una de las columnas (un segundo apellido, por ejemplo) es nula y contamina toda la expresión. La solución es envolver las columnas dudosas en COALESCE o usar CONCAT_WS.

El segundo descuido es esperar que CONCAT añada separadores por su cuenta. No lo hace: cada espacio, guion o coma entre los valores hay que incluirlo a mano como un argumento más. Cuando necesitas el mismo separador entre muchos valores, CONCAT_WS es bastante más cómodo.

Cuándo usar CONCAT

CONCAT es la opción adecuada para unir valores de una misma fila en un orden y formato concretos: nombres completos, descripciones, etiquetas o fragmentos de texto. Cuando quieras un separador común entre los elementos y que los valores nulos se ignoren, CONCAT_WS es mejor; y para unir valores de varias filas, la función indicada es GROUP_CONCAT.

En el siguiente artículo veremos CONCAT_WS, que concatena usando un separador definido e ignora los valores nulos.

Escrito por Eduardo Lázaro