GROUP_CONCAT e LEFT_JOIN questão - Nem todas as linhas retornadas
-
11-09-2019 - |
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 .
- É este um comportamento esperado MySQL?
- Existe alguma maneira eu poderia obter o resultado esperado usando GROUP_CONCAT ou outra função?
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