Cómo agrupar y concatenar columnas en SQL: Guía práctica

Estás revisando los resultados de una consulta a dos tablas en tu base de datos. Observas que todas las columnas devuelven resultados muy similares, pero hay una columna específica donde los valores cambian. Te preguntas si existe una forma inteligente de manejar esto: ¿cómo agrupar los datos semejantes en una sola fila, pero hacer que la columna que cambia concatene todos sus valores diferentes en una única celda?

Diagrama de transformación de datos SQL mostrando el agrupamiento de columnas idénticas y la concatenación de valores diferentes.
Comparación visual entre filas individuales y resultados agrupados con concatenación en SQL.

La respuesta es sí. Este patrón de consulta es bastante típico y útil cuando necesitas comparar resultados casi idénticos pero deseas consolidar las variaciones en una sola línea.

El patrón general: Agrupar y Concatenar

Para lograr lo que buscas, la lógica fundamental se basa en dos pasos claros:

  • Agrupar por todas las columnas que permanecen iguales entre las filas.
  • En la columna que sí cambia, aplicar una función de agregación para concatenar sus valores distintos en una sola celda.

Aunque la solución exacta varía ligeramente según el motor de base de datos que estés utilizando, el patrón general es muy consistente:

SELECT
    col1,
    col2,
    col3,
    STRING_AGG(col_diferente, ', ') AS col_diferente_concat
FROM tu_query_original
GROUP BY
    col1,
    col2,
    col3;

Aquí, col1, col2 y col3 representan las columnas que no cambian, mientras que col_diferente es la columna específica que deseas juntar.

Sintaxis según el motor de base de datos

A continuación, te detallo cómo implementar este patrón en los sistemas más comunes:

  • SQL Server (2017+) y PostgreSQL: Utilizan la función nativa STRING_AGG(col_diferente, ', ').
  • MySQL / MariaDB: Requieren usar la función de agrupamiento clásica GROUP_CONCAT(col_diferente SEPARATOR ', ').
  • Oracle: Emplean LISTAGG(col_diferente, ', ') WITHIN GROUP (ORDER BY col_diferente).

Ejemplo concreto de consulta

Para visualizarlo mejor, imagina una tabla con las columnas id, nombre y valor. Tienes registros donde el id es 1 con nombre A y valor X, seguido de otro registro con el mismo id 1, nombre A pero ahora con valor Y. Al aplicar la consulta agrupada:

SELECT
    id,
    nombre,
    STRING_AGG(valor, ', ') AS valor
FROM tabla
GROUP BY
    id,
    nombre;

El resultado final consolidará ambos registros en una sola fila para el id 1 y nombre A, mostrando la columna valor como «X, Y». Mientras que un registro con id 2 y nombre B simplemente mostrará su valor único, Z.

Manejando consultas complejas con JOINs

Un detalle avanzado para cuando tu query original proviene de un JOIN entre dos tablas: puedes encapsular esa lógica dentro de una subconsulta o CTE (Common Table Expression) antes de aplicar el agrupamiento.

Por ejemplo, podrías definir una CTE llamada base que contenga tu query original con los JOINs, y luego seleccionar las columnas necesarias sobre esa base final para agrupar:

WITH base AS (
    -- Tu query original aquí
)
SELECT
    col1,
    col2,
    STRING_AGG(col_diferente, ', ') AS col_diferente
FROM base
GROUP BY
    col1,
    col2;

Si necesitas ajustar la consulta exacta a tu caso particular, estaré encantado de revisar un pedazo real de tu query y adaptarla para que funcione perfectamente.