Como usar o GROUP BY para concatenar strings no MySQL?

351

Basicamente, a questão é como obter isso:

foo_id foo_name
1 A
1 B
2 C

para isso:

foo_id foo_name
1 AB
2 C
Paweł Hajdan
fonte
13
DOWNVOTE é realmente confuso nomear uma string de coluna, dando a ele um nome que se parece com um tipo de dados. Assim, quaisquer respostas também são afetados pelo que desde que as respostas parecem que estão especificando um tipo de dados quando estiver especificando um nome de coluna
barlop
2
O @barlop corrigiu isso editando perguntas e respostas.
ustun 29/08/19

Respostas:

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

Mais detalhes aqui .

No link acima,: GROUP_CONCATEsta função retorna um resultado de sequência com os valores não NULL concatenados de um grupo. Retorna NULL se não houver valores que não sejam NULL.

Graeme Perrow
fonte
a coluna resultante tem um limite de caracteres. veja aqui e os docs :)
marlo
18
SELECT id, GROUP_CONCAT(CAST(name as CHAR)) FROM table GROUP BY id

Fornecerá uma string delimitada por vírgula

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

: - No MySQL, você pode obter os valores concatenados das combinações de expressões. Para eliminar valores duplicados, use a cláusula DISTINCT . Para classificar valores no resultado, use a cláusula ORDER BY. Para classificar em ordem inversa , adicione a palavra-chave DESC (decrescente) ao nome da coluna pela qual você está classificando na cláusula ORDER BY. O padrão é ordem crescente; isso pode ser especificado explicitamente usando a palavra-chave ASC. O separador padrão entre valores em um grupo é vírgula (","). Para especificar um separador explicitamente, use SEPARATOR seguido pelo valor literal da string que deve ser inserido entre os valores do grupo. Para eliminar completamente o separador, especifique SEPARATOR '' .

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

OU

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

O resultado é truncado para o comprimento máximo fornecido pela variável de sistema group_concat_max_len, que possui um valor padrão de 1024 caracteres, então primeiro:

SET group_concat_max_len=100000000;

e depois, por exemplo:

SELECT pub_id,GROUP_CONCAT(cate_id SEPARATOR ' ') FROM book_mast GROUP BY pub_id
Waqar Alamgir
fonte
O resultado é truncado para o comprimento máximo fornecido pela variável de sistema group_concat_max_len, que possui um valor padrão de 1024 caracteres. docs
marlo 26/01
Qual é o escopo dessa group_concat_max_lenconfiguração? Conexão / sessão atual ou afetará outros clientes?
Frozen Flame
@FrozenFlame:> Se nenhum modificador estiver presente, o SET altera a variável da sessão. Se a variável não tiver valor de sessão, ocorrerá um erro. De dev.mysql.com/doc/refman/5.7/en/using-system-variables.html
arminrosu
3
Isso não responde à pergunta do OP, mas apenas adiciona informações úteis. Isso deve ser um comentário, não uma resposta.
Sean the Bean
11
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
Donald Duck
11

Ótimas respostas. Também tive um problema com o NULLS e consegui resolvê-lo incluindo um COALESCE dentro do GROUP_CONCAT. Exemplo da seguinte maneira:

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

Espero que isso ajude outra pessoa

Mauricio Alo
fonte