Question

Disons que mon schéma DB est la suivante:

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')

Si je lance une première requête pour obtenir tous les produits avec leurs utilisateurs (s'il y en a), je reçois ceci:

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

me semble bon. Maintenant, si je veux la même chose, sauf que je voudrais avoir un produit par ligne, avec les noms d'utilisateur concaténés (s'il y a des utilisateurs, sinon 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

S'il n'y a pas d'utilisateurs pour un produit, le GROUP_CONCAT empêche mysql de produire une ligne pour ce produit, même si il y a un LEFT JOIN .

  1. Est-ce un comportement MySQL attendu?
  2. Est-il possible que je pourrais obtenir le résultat attendu en utilisant GROUP_CONCAT ou une autre fonction?
Était-ce utile?

La solution

Ah, trouvé ma réponse:

Vous ne devriez jamais oublier le GROUP BY clause lorsque vous travaillez avec GROUP_CONCAT . Je manquais GROUP BY T_PRODUCT.id_product dans ma deuxième requête.

Je vais laisser la question en cas où quelqu'un est aussi distrait que je suis.

Modifier :

De cette réponse, je me suis dit que je peux aussi activer le mode SQL ONLY_FULL_GROUP_BY pour forcer MySQL à lancer une erreur dans le cas où le GROUP BY est manquant ou incorrect.

Autres conseils

Alternativement, vous pouvez utiliser un sous-requête, essai juste pour la performance

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top