Pergunta

Vamos dizer que meu esquema DB é a seguinte:

T_PRODUCT
id_product (int, primary)

two entries: (id_product =1) , (id_product =2)

T_USER
id_user (int, primary)
id_product (int, foreign key)
name_user (varchar)

two entries: (id_product=1,name_user='John') , (id_product=1,name_user='Mike')

Se eu executar uma primeira consulta para obter todos os produtos com seus usuários (se houver algum), fico com esta:

SELECT T_PRODUCT.id_product, T_USER.name_user 
FROM T_PRODUCT
LEFT JOIN T_USER on T_USER.id_product = T_PRODUCT.id_product;

>>
id_product name_user
1          John
1          Mike
2          NULL

Parece bom para mim. Agora, se eu quero a mesma coisa, exceto que eu gostaria de ter um produto por linha, com nomes de usuário concatenadas (se existem usuários, caso contrário, null):

SELECT T_PRODUCT.id_product, GROUP_CONCAT(T_USER.name_user) 
FROM T_PRODUCT
LEFT JOIN T_USER on T_USER.id_product = T_PRODUCT.id_product;

>>
id_product name_user
1          John,Mike

**expected output**:
id_product name_user
1          John,Mike
2          NULL

Se não houver usuários para um produto, os impede GROUP_CONCAT MySQL de produzir uma linha para este produto, mesmo que não haja um LEFT JOIN .

  1. É este um comportamento esperado MySQL?
  2. Existe alguma maneira eu poderia obter o resultado esperado usando GROUP_CONCAT ou outra função?
Foi útil?

Solução

Ah, encontrei a minha resposta:

Você nunca deve esquecer o GROUP BY cláusula quando se trabalha com GROUP_CONCAT . Eu estava faltando GROUP BY T_PRODUCT.id_product na minha segunda consulta.

Vou deixar a questão em caso de alguém é tão distraído quanto eu.

Editar :

A partir esta resposta , eu percebi que eu também pode ativar o modo de SQL ONLY_FULL_GROUP_BY para forçar o MySQL a lançar um erro no caso do GROUP BY está faltando ou está incorreto.

Outras dicas

Como alternativa, você poderia usar uma subconsulta, apenas teste para o desempenho

SELECT 
  T_PRODUCT.id_product, 
  (SELECT GROUP_CONCAT(T_USER.name_user) 
     FROM T_USER 
     WHERE T_USER.id_product = T_PRODUCT.id_product
  )
FROM T_PRODUCT
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top