views:

527

answers:

1

Hi I want to write a mysql statement which will return a list of results from one table along with a comma separated list of field from another table. I think an example might better explain it

Table 1
========================

id First_Name Surname
----------------------
1  Joe       Bloggs
2  Mike      Smith
3  Jane      Doe

Table 2
========================

id Person_Id Job_id
---------------------
1  1         1
2  1         2
3  2         2
4  3         3
5  3         4

I want to return a list of people with a comma separated list of job_ids. So my result set would be

id First_Name Surname job_id
------------------------------
1  Joe       Bloggs   1,2
2  Mike      Smith    2
3  Jane      Doe      3,4

I guess the sql would be something like

select id, First_Name, Surname, (SELECT job_id FROM Table 2) as job_id from Table 1

but obviously this does not work so need to change the '(SELECT job_id FROM Table 2) as job_id' part.

Hope this makes sense

Thanks John

+3  A: 

You may want to use the GROUP_CONCAT() function, as follows:

SELECT    t1.id, 
          t1.first_name, 
          t1.last_name,
          GROUP_CONCAT(DISTINCT job_id ORDER BY job_id SEPARATOR ',') job_id
FROM      Table1 t1
JOIN      Table2 t2 ON (t2.Person_id = t1.id)
GROUP BY  t1.id;

Let's test it with your example data:

CREATE TABLE Table1 (
    id int AUTO_INCREMENT PRIMARY KEY, 
    first_name varchar(50), 
    last_name varchar(50));

CREATE TABLE Table2 (
    id int AUTO_INCREMENT PRIMARY KEY, 
    person_id int,
    job_id int);

INSERT INTO Table1 VALUES (NULL, 'Joe', 'Bloggs');
INSERT INTO Table1 VALUES (NULL, 'Mike', 'Smith');
INSERT INTO Table1 VALUES (NULL, 'Jane', 'Doe');

INSERT INTO Table2 VALUES (NULL, 1, 1);
INSERT INTO Table2 VALUES (NULL, 1, 2);
INSERT INTO Table2 VALUES (NULL, 2, 2);
INSERT INTO Table2 VALUES (NULL, 3, 3);
INSERT INTO Table2 VALUES (NULL, 3, 4);

Result of the query:

+----+------------+-----------+--------+
| id | first_name | last_name | job_id |
+----+------------+-----------+--------+
|  1 | Joe        | Bloggs    | 1,2    | 
|  2 | Mike       | Smith     | 2      | 
|  3 | Jane       | Doe       | 3,4    | 
+----+------------+-----------+--------+

Note that by default, the result of GROUP_CONCAT() is truncated to the maximum length of 1024. However this can be set to a much larger value. Use the SET command if you require to modify it, as follows:

SET GLOBAL group_concat_max_len = 2048;
Daniel Vassallo
GROUP_CONCAT() is length limited, though. It's a wonderfully useful function, but only for small data sets. You can see what the limit is with `show variables like '%group_concat%'`
Marc B
@Mark: Thanks for the note. I've modified my answer to mention it.
Daniel Vassallo
Thanks for your reply Daniel it looks like just what I was after. However when I create the tables and run the query you have above the job_id field is returned as [BLOB - 3 B], [BLOB - 1 B], [BLOB - 3 B]. I have run the query using phpmyadmin and am running mysql 5 if this helps
John
@John: Unfortunately there is a known bug in MySQL regarding this issue. Do you have root access to the server? If yes, you can fix it as described here: http://bugs.mysql.com/bug.php?id=19473... If not, try setting `group_concat_max_len` to a value less than `512`, as described here: http://www.mail-archive.com/[email protected]/msg128227.html.
Daniel Vassallo
even though this is show as blob in phpmyadmin does it still contain the right data i.e. 1,2 etc in the case above?
John
@John: I'm not sure, as I have never replicated the bug personally. It seems that this problem was fixed in the latest versions of MySQL. However I would assume that it is just the datatype of the resultset that is incorrect: ie. It returns a resultset with a blob attribute instead of a varchar.
Daniel Vassallo