I want to be able to display a table with a list of people in one column and a string of their orders in another.
People
========
person_id
fname
lname
Orders
========
order_id
person_id
product_id
Products
=========
product_id
productname
I have the following code:
SELECT people.fname, people.lname, products.productname
FROM people
INNER JOIN orders ON people.person_id = orders.person_id
INNER JOIN products ON products.product_id = orders.product_id
ORDER BY lname
...
$rows = $result->num_rows;
while($row = $result->fetch_assoc()) {
echo "<tr><td>Edit</td>
<td>".$row["lname"].", ".$row['fname']."</td>
<td>".$row['productname']."</td></tr>";
}
This displays:
Smith, Bob | Item 1
Smith, Bob | Item 2
Smith, Bob | Item 3
Roberts, Jill | Item 2
etc..
What I want is for it to display:
Smith, Bob | Item 1, Item 2, Item 3
Roberts, Jill | Item 2
How do I show the name (based on person_id) only once and then a list of their orders in another column?
In MySQL, you have to use the GROUP_CONCAT
function. For example something like this:
SELECT CONCAT(LNAME,", ",FNAME), GROUP_CONCAT(PRODUCTNAME)
FROM PEOPLE P, PRODUCTS PR, ORDERS O
WHERE P.PERSON_ID = O.PERSON_ID
AND O.PRODUCT_ID = PR.PRODUCT_ID
GROUP BY (LNAME, FNAME);
Php oriented solution :
You could store your product names in an array, using the person's name as a key :
$rows = $result->num_rows;
$data = array();
while($row = $result->fetch_assoc())
{
$name = $row["lname"].", ".$row['fname'];
$data[$name][] = $row['productname'];
}
Then, you'll just have to loop through this array :
foreach($data as $name => $products)
{
echo "<tr><td>Edit</td><td>".$name."</td>";
foreach($products as $productname)
{
echo "<td>".$productname."</td>";
}
echo "<tr>";
}