¿Cómo usar GROUP BY para concatenar cadenas en MySQL?

351

Básicamente, la pregunta es cómo llegar a esto:

foo_id foo_name
1 A
1 B
2 C

a esto:

foo_id foo_name
1 AB
2 C
Paweł Hajdan
fuente
13
DOWNVOTE es realmente confuso nombrar una cadena de columna, dándole un nombre que se parece a un tipo de datos. Por lo tanto, cualquier respuesta también se ve afectada por eso, ya que parece que están especificando un tipo de datos cuando especifican un nombre de columna
barlop
2
@barlop corrigió eso editando preguntas y respuestas.
Ustun

Respuestas:

164
SELECT id, GROUP_CONCAT( string SEPARATOR ' ') FROM table GROUP BY id

Más detalles aquí .

Desde el enlace anterior GROUP_CONCAT: Esta función devuelve un resultado de cadena con los valores concatenados no NULL de un grupo. Devuelve NULL si no hay valores no NULL.

Graeme Perrow
fuente
la columna resultante tiene un límite en caracteres. ver aquí y los documentos :)
marlo
18
SELECT id, GROUP_CONCAT(CAST(name as CHAR)) FROM table GROUP BY id

Te dará una cadena delimitada por comas

Wayne
fuente
17
SELECT id, GROUP_CONCAT(name SEPARATOR ' ') FROM table GROUP BY id;

: - En MySQL, puede obtener los valores concatenados de combinaciones de expresiones. Para eliminar valores duplicados, use la cláusula DISTINCT . Para ordenar los valores en el resultado, use la cláusula ORDER BY. Para ordenar en orden inverso , agregue la palabra clave DESC (descendente) al nombre de la columna por la que está ordenando en la cláusula ORDER BY. El valor predeterminado es el orden ascendente; esto puede especificarse explícitamente usando la palabra clave ASC. El separador predeterminado entre valores en un grupo es una coma (","). Para especificar un separador explícitamente, use SEPARATOR seguido del valor literal de la cadena que debe insertarse entre los valores del grupo. Para eliminar el separador por completo, especifique SEPARADOR '' .

GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val])

O

mysql> SELECT student_name,
    ->     GROUP_CONCAT(DISTINCT test_score
    ->               ORDER BY test_score DESC SEPARATOR ' ')
    ->     FROM student
    ->     GROUP BY student_name;
Exundoz
fuente
15

El resultado se trunca a la longitud máxima dada por la variable de sistema group_concat_max_len, que tiene un valor predeterminado de 1024 caracteres, por lo que primero hacemos:

SET group_concat_max_len=100000000;

y luego, por ejemplo:

SELECT pub_id,GROUP_CONCAT(cate_id SEPARATOR ' ') FROM book_mast GROUP BY pub_id
Waqar Alamgir
fuente
El resultado se trunca a la longitud máxima dada por la variable de sistema group_concat_max_len, que tiene un valor predeterminado de 1024 caracteres. docs
marlo
¿Cuál es el alcance de esta group_concat_max_lenconfiguración? Conexión / sesión actual, ¿o afectará a otros clientes?
Frozen Flame
@FrozenFlame:> Si no hay un modificador presente, SET cambia la variable de sesión. Si la variable no tiene valor de sesión, se produce un error. De dev.mysql.com/doc/refman/5.7/en/using-system-variables.html
arminrosu
3
Esto no responde a la pregunta del OP sino que simplemente agrega información útil. Esto debería ser un comentario, no una respuesta.
Sean the Bean
1
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y la haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
Donald Duck
11

Grandes respuestas También tuve un problema con NULLS y logré resolverlo al incluir una COALESCE dentro de GROUP_CONCAT. Ejemplo de la siguiente manera:

SELECT id, GROUP_CONCAT(COALESCE(name,'') SEPARATOR ' ') 
FROM table 
GROUP BY id;

Espero que esto ayude a alguien más

Mauricio Alo
fuente