Tema SQL
GROUP_CONCAT() (MySQL / MariaDB)
Agregado que concatena valores de un grupo en una sola cadena, con separador configurable y orden opcional. Muy usado para listas legibles en informes; el límite de longitud lo controla group_concat_max_len.
Descripción
GROUP_CONCAT([DISTINCT] expr [ORDER BY …] [SEPARATOR str]) resume muchas filas en un texto. DISTINCT elimina duplicados antes de concatenar; ORDER BY define el orden de los valores en la cadena resultante; SEPARATOR cambia el coma por defecto (p. ej. salto de línea o « | »). En sesiones con group_concat_max_len bajo, el resultado se trunca sin error explícito en algunos modos: revisa el valor en entornos de producción. No es estándar SQL: en otros motores se usan STRING_AGG (SQL Server, PostgreSQL ≥14 con sintaxis similar), LISTAGG (Oracle) o agregados personalizados. Para datos jerárquicos grandes, una cadena gigante puede ser señal de que conviene otra forma de serialización (JSON_ARRAYAGG en motores que lo permitan).
Estructura general
Forma habitual de la sentencia: orden de cláusulas, qué parte filtra, agrupa o proyecta columnas, y qué devuelve el motor. Cópiala como plantilla y sustituye nombres por tus tablas reales.
GROUP_CONCAT([DISTINCT] expresión [ORDER BY …] [SEPARATOR 'cad'])
Componentes
Cada componente tiene un papel concreto en la ejecución lógica de la sentencia. Léelos en orden: así entiendes qué puedes omitir, qué es obligatorio y qué expresiones son válidas en cada sitio según tu motor.
- Contexto GROUP BY
- Se usa junto a GROUP BY; las columnas no agrupadas deben ir dentro del agregado o en GROUP BY.
- DISTINCT
- Evita repetir valores idénticos en la lista concatenada.
- ORDER BY interno
- Ordena los valores antes de concatenar (no confundir con ORDER BY del SELECT exterior).
- Límite de longitud
- Ajusta group_concat_max_len si concatenas muchos valores.
Ejemplos
Ejemplo 1
SELECT departamento_id,
GROUP_CONCAT(nombre ORDER BY nombre SEPARATOR ', ') AS empleados
FROM empleados
GROUP BY departamento_id;
Ejemplo 2
SELECT usuario_id,
GROUP_CONCAT(DISTINCT tag ORDER BY tag SEPARATOR ' | ') AS tags
FROM usuario_tags
GROUP BY usuario_id;
Los ejemplos son ilustrativos. En producción usa consultas parametrizadas (prepared statements), revisa índices y aplica el principio de menor privilegio en cuentas de base de datos.