(There is an updated version of this post here)
MySQL has useful extention to the GROUP BY operation: function GROUP_CONCAT:
GROUP_CONCAT(expr) – This function returns a string result with the concatenated non-NULL values from a group.
Where it can be useful?
For example to get PHP array without looping inside PHP:
Table:
|
1 |
CREATE TABLE services (<br>id INT UNSIGNED NOT NULL, <br>client_id INT UNSIGNED NOT NULL, <br>KEY (id));<br>INSERT INTO services <br>VALUES (1,1),(1,2),(3,5),(3,6),(3,7);<br><br>SELECT id,client_id FROM services WHERE id = 3;<br>+----+-----------+<br>| id | client_id |<br>+----+-----------+<br>| 3 | 5 | <br>| 3 | 6 | <br>| 3 | 7 | <br>+----+-----------+<br><br>SELECT id,GROUP_CONCAT(client_id) FROM services WHERE id = 3 GROUP BY id; <br>+----+-------------------------+<br>| id | GROUP_CONCAT(client_id) |<br>+----+-------------------------+<br>| 3 | 5,6,7 | <br>+----+-------------------------+ |
Handling in PHP:
old way:
|
1 |
<!--?php $res=$mysqli--->query("SELECT id,client_id FROM services WHERE id = 3");<br> while ($row = $res->fetch_array(MYSQLI_ASSOC)) {<br> $result[] = $row['client_id'];<br>}<br>$res->free();<br>?> |
with group_concat:
|
1 |
<!--?php $res=$mysqli--->query("SELECT id,GROUP_CONCAT(client_id) as clients FROM services WHERE id = 3 GROUP BY id");<br>$row = $res->fetch_array(MYSQLI_ASSOC);<br>$result = explode(',', $row['clients']); // $row['clients'] contains string 5,6,7<br>$res->free();<br>?> |
This should work faster, as we remove loop from PHP to MySQL server side.
Also it can be handy to use result concatenated string as part of IN statement:
|
1 |
<!--?php $res=$mysqli--->query("SELECT id,GROUP_CONCAT(client_id) as clients FROM services WHERE id = 3 GROUP BY id");<br>$row = $res->fetch_array(MYSQLI_ASSOC);<br>$result = $row['clients']; // $row['clients'] contains string 5,6,7<br>$res->free();<br><br>$resclients=$mysqli->query("SELECT id,client_name FROM clients WHERE id = IN ($result)");<br>// handle $resclients<br><br>?> |
Sure, last example can be handled with one query with joins, but sometimes we need the temporary ids in clients code, for example to execute query on another server.
One more thing: you may want to add ORDER BY NULL statement after GROUP_BY to avoid
unnecessary sorting with filesort
Resources
RELATED POSTS