views:

199

answers:

2

Let's say my DB Scheme is as follows:

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

If I run a first query to get all products with their users (if there are any), I get this:

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

Looks good to me. Now if I want to the same thing, except I'd like to have one product per line, with concatenated user names (if there are any users, otherwise 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

If there are no users for a product, the GROUP_CONCAT prevents mysql from producing a line for this product, even though there's a LEFT JOIN.

  1. Is this an expected MySQL behaviour?
  2. Is there any way I could get the expected output using GROUP_CONCAT or another function?
+1  A: 

Ah, found my answer:

You should never forget the GROUP BY clause when working with GROUP_CONCAT. I was missing GROUP BY T_PRODUCT.id_product in my second query.

I'll leave the question up in case someone is as absent-minded as I am.

Edit:

From this answer, I figured I can also activate the SQL Mode ONLY_FULL_GROUP_BY to force MySQL to throw an error in case the GROUP BY is missing or incorrect.

altermativ
MySql doesn't complain when you leave out a group by? I believe T-Sql and Oracle both do...
jle
@jle: MySQL is lax on the `GROUP BY` clause by design
OMG Ponies
Yes, see http://stackoverflow.com/questions/1645921/mysql-group-by-behavior/1646121#1646121
Bill Karwin
Thank you Bill, now I know I can use the sql mode "ONLY_FULL_GROUP_BY" to make it behave like the other RDBMS and throw an error when the GROUP BY is missing.
altermativ
A: 

Alternately, you could use a subquery, just test for 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
GApple