I have e.g. the following data returned from a query, each name is an item:
id name comment
1 FF hey
1 FF hey back!
2 L
Don't confuse data access with output and you will have an easier time attacking this sort of problem.
//Fetch and Sort
$data = array();
while ($row = mysql_fetch_array($result)){
$item = $row['item'];
if(!isset($data[$item]) {
$data[$item] = array():
}
$data[ = $data[$item][] = $row['comment'];
}
//Output
foreach($data as $item => $comments) {
echo '<li><div class=className><div class=itemName>'.$item.'</div>';
foreach($comments as $comment) {
echo '<div class=newRow>'.$comment.'</div>';
}
echo '</div></li>';
}
You can use GROUP_CONCAT() on your mysql query to group all the comments together for each name
SELECT id, name
GROUP_CONCAT(comment) AS comment
FROM table
GROUP BY name;
then explode() the $row[comment]
in your php code
while ($row = mysql_fetch_array($result)){
echo '<li><div class=className><div class=itemName>'.$row['name'].'</div>';
if($row['comment'] != ""){
$comments = explode(",",$row['comment']);
foreach($comments as $comment){
echo '<div class=newRow>'.$comment.'</div>';
}
}
echo '</div></li>';
}
Edit
Thanks to @CBroe, I now know that GROUP_CONCAT()
has a group_concat_max_len default of 1024. You will want to increase this before running the GROUP_CONCAT()
query -
SET [GLOBAL | SESSION] group_concat_max_len = 10240; // must be in multiples of 1024
SELECT id, name
GROUP_CONCAT(comment) AS comment
FROM table
GROUP BY name;
you will also need to be aware of max_allowed_packet as this is the limit you can set var_group_concat_max_len
to.
note: mysql_query()
does not allow multiple queries, so you will need to do 2 mysql_query()
, and you can use SET SESSION ...
so that all queries in your current session have that max_len
. It would be better to change from mysql_
functions (which are depreciated) and change to mysqli_ or PDO as they offer multiple query option. also check out - http://php.net/manual/en/mysqlinfo.api.choosing.php
If you are not getting the data back sorted by id already, add to the end of your query:
ORDER BY name
which will retrieve the same list ordered by id. Then in your while loop, add a variable that keeps track of the last item name that you saw. If it changes, add a new li, otherwise, add the comment on to the end of your current list.