Posso concatenar várias linhas do MySQL em um campo?

Usando o MySQL , posso fazer algo como:

 SELECT hobbies FROM peoples_hobbies WHERE person_id = 5; 

Minha saída:

 shopping fishing coding 

mas em vez disso eu quero apenas 1 linha, 1 col:

Saída esperada:

 shopping, fishing, coding 

O motivo é que estou selecionando vários valores de várias tabelas e, depois de todas as junções, tenho muito mais linhas do que gostaria.

Eu procurei por uma function no MySQL Doc e não parece que as CONCAT ou CONCAT_WS aceitem conjuntos de resultados, então alguém aqui sabe como fazer isso?

Você pode usar o GROUP_CONCAT :

 SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id 

Como Ludwig afirmou em seu comentário, você pode adicionar o operador DISTINCT para evitar duplicatas:

 SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id 

Como Jan declarou em seu comentário, você também pode classificar os valores antes de implodi-los usando ORDER BY :

 SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id 

Como Dag declarou em seu comentário, há um limite de 1024 bytes no resultado. Para resolver isso, execute esta consulta antes da sua consulta:

 SET group_concat_max_len = 2048 

Claro, você pode mudar 2048 acordo com suas necessidades. Para calcular e atribuir o valor:

 SET group_concat_max_len = CAST( (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ') FROM peoples_hobbies GROUP BY person_id) AS UNSIGNED ) 

Dê uma olhada no GROUP_CONCAT se sua versão do MySQL (4.1) o suportar. Veja a documentação para mais detalhes.

Seria algo parecido com:

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') FROM peoples_hobbies WHERE person_id = 5 GROUP BY 'all'; 

Sintaxe alternativa para concatenar várias linhas individuais

AVISO: Este post vai deixar você com fome.

Dado:

Eu me vi querendo selecionar várias linhas individuais – em vez de um grupo – e concatenar em um determinado campo.

Digamos que você tenha uma tabela de IDs de produtos e seus nomes e preços:

 +------------+--------------------+-------+ | product_id | name | price | +------------+--------------------+-------+ | 13 | Double Double | 5 | | 14 | Neapolitan Shake | 2 | | 15 | Animal Style Fries | 3 | | 16 | Root Beer | 2 | | 17 | Lame T-Shirt | 15 | +------------+--------------------+-------+ 

Então você tem um ajax extravagante que lista esses filhotes como checkboxs de seleção.

Seu usuário com hipopótamo faminto seleciona 13, 15, 16 . Nenhuma sobremesa para ela hoje …

Encontrar:

Uma maneira de resumir o pedido do usuário em uma linha, com o mysql puro.

Solução:

Use GROUP_CONCAT com a cláusula IN :

 mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16); 

Quais saídas:

 +------------------------------------------------+ | order_summary | +------------------------------------------------+ | Double Double + Animal Style Fries + Root Beer | +------------------------------------------------+ 

Solução de bônus:

Se você quiser o preço total também, coloque SUM() :

 mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary, SUM(price) AS total FROM product WHERE product_id IN (13, 15, 16); +------------------------------------------------+-------+ | order_summary | total | +------------------------------------------------+-------+ | Double Double + Animal Style Fries + Root Beer | 10 | +------------------------------------------------+-------+ 

PS: Desculpas se você não tem um In-N-Out nas proximidades …

Você pode alterar o comprimento máximo do valor GROUP_CONCAT configurando o parâmetro group_concat_max_len .

Veja detalhes na documentação do MySQL .

Há uma function GROUP Aggregate, GROUP_CONCAT .

No meu caso, eu tinha uma fila de IDs, e era necessário convertê-la em char, caso contrário, o resultado era codificado em formato binário:

 SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table 

Use a variável de session MySQL (5.6.13) e o operador de atribuição como o seguinte

 SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a; 

então você pode obter

 test1,test11 

Eu tinha uma consulta mais complicada e descobri que precisava usar o GROUP_CONCAT em uma consulta externa para que funcionasse:

Consulta Original:

 SELECT DISTINCT userID FROM event GROUP BY userID HAVING count(distinct(cohort))=2); 

Imploded:

 SELECT GROUP_CONCAT(sub.userID SEPARATOR ', ') FROM (SELECT DISTINCT userID FROM event GROUP BY userID HAVING count(distinct(cohort))=2) as sub; 

Espero que isso possa ajudar alguém.

Tente isto:

 DECLARE @Hobbies NVARCHAR(200) = ' ' SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;