Eu posso concatenar várias linhas de MySQL em um campo?
-
07-07-2019 - |
Pergunta
Usando MySQL
, posso fazer algo como:
SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;
Minha saída:
shopping
fishing
coding
mas eu só quero 1 linha, 1 col:
saída esperada:
shopping, fishing, coding
A razão é que eu estou selecionando vários valores de várias tabelas, e depois de toda a junta Eu tenho muito mais linhas do que eu gostaria.
Eu olhei para uma função na MySQL Doc e não se parece com as funções CONCAT
ou CONCAT_WS
aceitar conjuntos de resultados, então alguém aqui sabe como fazer isso?
Solução
Você pode usar 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
de duplicatas evitar:
SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;
Como Jan indicado no seu comentário, você também pode classificar os valores antes da implosão-lo usando ORDER BY
:
SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;
Como Dag indicado no seu comentário, existe um limite de 1.024 bytes no resultado. Para resolver isso, executar esta consulta antes de 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
);
Outras dicas
Alternate sintaxe para concatenar várias linhas individuais
AVISO:. Este post vai fazer você com fome
Dada:
Eu encontrei-me querer de seleção múltipla, linhas individuais ao invés de em um grupo e concatenar em um determinado campo.
Vamos dizer que você tem 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 |
+------------+--------------------+-------+
Em seguida, você tem algum ajax fantasia-schmancy que as listas estes filhotes de cachorro fora como caixas de seleção.
Seu usuário com fome-hipopótamo seleciona 13, 15, 16
. Não sobremesa para ela hoje ...
Localizar:
Uma maneira de resumir fim do seu usuário em uma linha, com mysql puro.
Solução:
Use GROUP_CONCAT
com a a cláusula IN
:
mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16);
Que resultados:
+------------------------------------------------+
| order_summary |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+
Bonus Solução:
Se quiser que o preço total também, lance em 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
definindo o parâmetro group_concat_max_len
.
Veja mais detalhes no MySQL documantation .
Há uma função de grupo agregado, GROUP_CONCAT .
No meu caso eu tinha uma fila de IDs, e era necessário lançá-lo aos char, caso contrário, o resultado foi codificado em formato binário:
SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table
Use MySQL (5.6.13) variável de sessão e 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 tive uma consulta mais complicada, e descobriu que eu tinha que usar GROUP_CONCAT
em uma consulta externa para obtê-lo para o trabalho:
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;
Para alguém olhando aqui como usar GROUP_CONCAT
com subconsulta - publicar esse exemplo
SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid
Assim GROUP_CONCAT
deve ser utilizado dentro da subconsulta, não envolvê-lo.
temos duas vias para colunas concatenar em MySql
select concat(hobbies) as `Hobbies` from people_hobbies where 1
ou
select group_concat(hobbies) as `Hobbies` from people_hobbies where 1