Sort items by category - php

I have a table containing the following records:
product_id | title | category
------------------------------------
1 | apple | mobile
2 | android | mobile
3 | dell | desktop
4 | hp | desktop
and the following query:
$sql = "SELECT product_id, title, category FROM products ORDER BY category";
$stmt = $db->prepare($sql);
$stmt->execute();
while($results = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo $results["product_id"];
echo $results["title"];
echo $results["category"];
}
The question is how to split the results and display all records in a list sorted by category as below:
Mobile
Apple
Android
Desktop
Dell
HP

Group your records after get the result set:
$products = array();
while ($results = $stmt->fetch(PDO::FETCH_ASSOC))
{
$products[$results['category']][] = array(
'product_id' => $results['product_id'],
'title' => $results['title']
);
}
foreach ($products as $category => $productList)
{
echo $category . '<br>';
foreach ($productList as $product)
{
echo $product['title'] . '<br>';
}
echo '<hr />';
}

Use SELECT * FROM products GROUP BY category ORDER BY title

After sorting your items (ORDER BY category, title), do something like this:
$last_category = "";
while(/* get a row here */) {
if( $last_category != $row['category']) {
if( $last_category != "") echo "</ul>";
echo "<ul>";
$last_category = $row['category'];
}
echo "<li>".$row['title']."<li>";
}
if( $last_category != "") echo "</ul>";

SELECT * FROM products ORDER BY category. This is to sort using category, your example output file seems different what are you trying to do?

Related

Fetch Mysql Results into serialized data

I have this table:
| id | related_id |
| 1 | 100 |
| 1 | 200 |
| 1 | 300 |
| 2 | 400 |
| 2 | 500 |
| 2 | 600 |
I need to retrieve serialized data as:
a:3:{i:1;s:3:"100";i:2;s:3:"200";i:3;s:3:"300";}
Query
SELECT id, related_id from mytable where id = 1;
I'm trying to get this using 'while'
$result = $link->query($query);
$item = array();
while($f = $result->fetch_assoc()){
$id = $f['id'];
if ($id == $f['id']){
$item[] = $f['related_id'];
}
print serialize($item);
break; // for test
}
SOLUTION that works for me (provided by Erwin - Thanks!)
$item = array();
while($f = $result->fetch_assoc()) {
$id = $f['id'];
if (!array_key_exists($id, $item)) {
$item[$id] = [1 => $f['related_id']];
} else {
$item[$id][] = $f['related_id'];
}
}
foreach ($item as $value) {
print serialize($value) . PHP_EOL;
}
Collect first each related_id and store to id array with your while loop. Then print each using foreach.
$item = array();
while($f = $result->fetch_assoc()) {
$id = $f['id'];
if (!array_key_exists($id, $item)) { // create id array if not exist
$item[$id] = [1 => $f['related_id']]; // To start with index 1
} else {
$item[$id][] = $f['related_id']; // Push each new related_id
}
}
foreach ($item as $value) {
print serialize($value); // Print each serialized
echo '<br>'; // New line
}
What you are trying to do is something like this:
$result = $link->query($query);
$items = array();
while($f = $result->fetch_assoc()){
$id = $f['id'];
if(!isset($items[$id])) {
$items[$id] = array();
}
$items[$id][] = $f['related_id'];
}
foreach($items as $item) {
print serialize($item);
}
For your serialized string, you have to work with an array with related_id in the second layer. The first layer is to save all related_id in an array with the same id.
You have 6 rows, 3 have id 1 and 3 have id 2. You are specifying that you want to use these ids as array keys so you will end up with 2 arrays, each holding 3 values.
If you want each row in its own array you do this:
while($f = $result->fetch_assoc()){
$item[] = array($f['id'] => $f['related_id']);
}

Remove Duplicates in while loop PHP

I'm trying to remove duplicate results from my SQL query using PHP.
table categories:
id | name
1 | sony
2 | nintendo
table subcategories:
id | name | category_id
1 | playstation | 1
2 | playstation2 | 1
3 | wii | 2
table video_games
id | name | subcategories
1 | grand theft auto | 1,2
2 | super mario | 3
My PHP code:
$query = $database->query('SELECT id FROM subcategories WHERE category_id = "'.$_GET['id'].'"');
while($return = $query->fetch()) {
$subcategories = $return['id'];
$request = '%'.$subcategories.'%';
$game_query = $database->prepare('SELECT * FROM video_games WHERE subcategories LIKE :request');
$game_query->bindValue('request', $request);
$game_query->execute();
if($game_query->rowCount() > 0) {
while($game_return = $game_query->fetch()) {
echo $game_return['name'];
}
}
}
My code works but I have duplicate video games when there have multi subcategories.
I tried using SELECT DISTINCT * FROM video_games WHERE subcategories LIKE :request but same problem.
Any idea to remove duplicate results using SQL or PHP ?
MySql is able to solve this problem by its own means.
Use 'DISTINCT' and 'FIND_IN_SET'.
Like this:
"SELECT DISTINCT
vg.id,
vg.name,
vg.subcategories
FROM
video_games vg
WHERE
FIND_IN_SET( (SELECT id FROM subcategories WHERE category_id='".$_GET['id'])."' , vg.subcategories ) > 0 "
and also you can use array_unique at first save video game names in an array and next remove duplicate value.
.
.
.
your code
.
.
$game_query->execute();
if($game_query->rowCount() > 0) {
$fetch =array_unique($game_query->fetch());
foreach ($fetch as $key => $value){
echo $value;
}
}
test
<pre>
<?php
$arr=array("name"=>"1","name2"=>"2","name1"=>"2","name3"=>"3","name4"=>"1","name5"=>"2","name6"=>"3","name7"=>"22");
print_r($arr);
$fetch =array_unique($arr);
print_r($fetch);
foreach ($fetch as $key => $value)
echo $key."=>".$value."<br>";
?>
</pre>
You can save video game names in an array, and print it afterwards. For example:
$games = array();
$query = $database->query('SELECT id FROM subcategories WHERE category_id = "'.$_GET['id'].'"');
while($return = $query->fetch()) {
$subcategories = $return['id'];
$request = '%'.$subcategories.'%';
$game_query = $database->prepare('SELECT * FROM video_games WHERE subcategories LIKE :request');
$game_query->bindValue('request', $request);
$game_query->execute();
if($game_query->rowCount() > 0) {
while($game_return = $game_query->fetch()) {
if (!in_array($game_return['name'], $games)) {
$games[] = $game_return['name'];
}
}
}
}
//now print the games
foreach ($games as $game) {
echo $game;
}
EDIT If you want more than just 'name', you can expand $games array with $key => $value combination. For example:
. . .
while($game_return = $game_query->fetch()) {
foreach ($games as $game) {
if ($game['name'] === $game_return['name']]) {
continue 2;
}
}
$games[] = array(
'name' => $game_return['name'],
'price' => $game_return['price'],
)
}
And afterwards print it like:
foreach ($games as $game) {
echo $game['name'];
echo $game['price'];
}

While Loop echos only 1 value twice

I have a 2 tables called forums and forum_categories in database
forum_categories
cat_id
forums
cat_id
I am trying to count the total for each category for some reason it displays total record for all records.
I have 2 categories so far in the database
first category has value of 1
second category has value of 2
In category one, I have two forums that has a cat_id of 1
In category two, I have one forum that has a cat_id of 2
it displays
category 1 -------------------- 3 ---------------
category 2 -------------------- 3 ---------------
when it should display
category 1 -------------------- 2 ---------------
category 2 -------------------- 1 ---------------
$topics_count always displays 3.
$sql = "SELECT * FROM forum_categories, forums WHERE forum_categories.cat_id = forums.cat_id GROUP BY forum_categories.cat_id";
$result = query($sql);
$sql2 = "SELECT fc.cat_title COUNT(f.forum_id) FROM forums as f LEFT JOIN forum_categories fc ON (f.cat_id = fc.cat_id) GROUP BY f.cat_id";
$result2 = query($sql2);
$topics_count = count($result2);
while (($row = mysqli_fetch_assoc($result)) != false) {
$cat_id = $row['cat_id'];
$cat_title = $row['cat_title'];
$forum_name = $row['forum_name'];
echo "<tr>";
echo "<td>$cat_id</td>";
echo "<td><a href='viewforum.php?f={$cat_id}'>$cat_title</a><br>$forum_name admin</td>";
echo "<td>$topics_count</td>";
echo "<td>0</td>";
echo "</tr>";
}
This bit of code below gives you all results:
$sql2 = "SELECT * FROM forums WHERE cat_id = cat_id";
$result2 = query($sql2);
$topics_count = row_count($result2); // here this would be 3*
*in case of 2 for cat1 + 1 for cat2 and you echo this in each table row as:
echo "<td>$topics_count</td>";
therefore you see the total number (3) on both rows.
What you are actually trying is to join forums and forum_categories table, get the forum_categories.cat_title and COUNT(forums.cat_id) while grouping the results by forums.cat_id
SELECT
fc.cat_title,
COUNT(f.forum_id)
FROM forums as f
LEFT JOIN forum_categories fc ON (f.cat_id = fc.cat_id)
GROUP BY f.cat_id
Here is the same demo fiddle I've sent you yesterday.
Your query would then return you something like:
Demo Forum 1 | 2
Demo Forum 2 | 1
UPDATE:
$sql2 = "SELECT
fc.cat_id,
fc.cat_title,
f.forum_name,
COUNT(f.forum_id) as count
FROM forums as f
LEFT JOIN forum_categories fc ON (f.cat_id = fc.cat_id)
GROUP BY f.cat_id";
$result2 = query($sql2);
while (($row = mysqli_fetch_assoc($result)) != false) {
$cat_id = $row['cat_id']; // category id
$cat_title = $row['cat_title']; // category title
$forum_name = $row['forum_name']; // forum name
$count = $row['count']; // count of forum_id (grouped by cat_id)
echo "<tr>";
echo "<td>$cat_id</td>";
echo "<td><a href='viewforum.php?f={$cat_id}'>$cat_title</a><br>$forum_name admin</td>";
echo "<td>$count</td>";
echo "<td>0</td>";
echo "</tr>";
}
Here, I'm pretty sure the count would be okay, but not sure about "Forum Name".
try this
replace this
while (($row = mysqli_fetch_assoc($result)) != false) {
with this
while ($row = mysqli_fetch_assoc($result)) {

How to place values inside table cell according to combination of table header and first row value?

the below is my mysql table structure, the values inside are not fixed and can get changed by admin.
town_name | product_name| pending_quantity
------------------------------------------
Jaipur | Mobile | 5
Jaipur | Charger | 3
Surat | wallet | 2
Surat | Mobile | 1
Surat | battery | 3
Surat | cover | 2
In my php code, i stored all these values in 3 different arrays (one for each column) and everything is fine. I want to show this data in HTML table but the structure it needs to be shown is a problem to me. Below is the expected HTML table structure.
town_name | Mobile | charger | wallet | Battery | cover
-------------------------------------------------------
Jaipur | 5 | 3 | | |
Surat | 1 | | 2 | 3 | 2
So far, I've achieved to show rows and column headers the way it should be. But am now unable to put the pending quantity values in its place.
This is my php code if its of any help
<tbody>
<?php
$count = 1;
$row=0;
foreach($townid as $townKey=>$townValue) {
echo "<tr>";
echo "<td>$count</td>";
echo "<td>$townValue</td>";
foreach($items as $productKey=>$productValue) {
echo "<td>$pendingqty[$townKey]</td>";
$row++;
}
$row++;
echo "</tr>";
$count++;
}
?>
</tbody>
The column headers (mobile, charger etc etc) are dynamic and the town names are also dynamic. Please help me in achieving the desired result via mysql or html.
PHP code that gets values inside arrays
$townid2 = array();
$itemname = array();
$pendingqty = array();
$items = array();
$query = mysql_query("select o.town_id as townid, od.item_name as itemname, sum(od.pending_qnty) as pendingqty FROM tbl_order o JOIN tbl_order_data od on o.id = od.order_id where month(o.order_date)='1' GROUP BY o.town_id, od.item_name ");
while($row = mysql_fetch_array($query)) {
$townid2[]=$row['townid'];
$pendingqty[] = $row['pendingqty'];
$items[] = $row['itemname'];
}
$townid = array_unique($townid2, SORT_REGULAR);
$query2 = mysql_query("select od.item_name FROM tbl_order_data od JOIN tbl_order o on o.id=od.order_id where od.order_id IN (select id from tbl_order where month(order_date)='1') group by od.item_name order by o.item_name ");
$productArray = array();
while($row2 = mysql_fetch_array($query2)) {
$productArray[] = $row2['item_name'];
}
Here is how I would do it (I'm using mysql_query because you did, but it's deprecated so you really should switch):
$things = array();
$columns = array('Mobile','charger','wallet','Battery','cover'); //this can/should be populated dynamically using a distinct product query, but I'm hard-coding it because I'm lazy
$query = mysql_query("select o.town_id as townid, od.item_name as itemname, sum(od.pending_qnty) as pendingqty FROM tbl_order o JOIN tbl_order_data od on o.id = od.order_id where month(o.order_date)='1' GROUP BY o.town_id, od.item_name");
while($row = mysql_fetch_array($query)) {
$things[$row['townid']][$row['itemname']] = $row['pendingqty'];
}
... //whatever code until you're ready for the table
echo "<table><thead><tr>";
foreach($columns as $column){
echo "<th>".$column."</th>";
}
echo "</tr><thead><tbody>";
foreach($things as $key=>$value){
echo "<tr><td>".$key."</td>";
foreach($columns as $column){
echo "<td>".(isset($value[$column]) ? $value[$column] : null)."</td>";
}
echo "</tr>";
}
echo"</tbody></table>";
Here's my take
$itemnames = array();
$pendingqtys = array();
$query = mysql_query("SELECT
od.item_name AS itemname
FROM
tbl_order o
JOIN
tbl_order_data od ON o.id = od.order_id
WHERE
MONTH(o.order_date) = '1'
GROUP BY o.town_id");
while($row = mysql_fetch_array($query)) {
$itemnames[] = $row['itemname'];
}
$query = null;
$query = mysql_query("SELECT
o.town_id AS townid,
od.item_name AS itemname,
SUM(od.pending_qnty) AS pendingqty
FROM
tbl_order o
JOIN
tbl_order_data od ON o.id = od.order_id
WHERE
MONTH(o.order_date) = '1'
GROUP BY o.town_id , od.item_name");
while($row = mysql_fetch_array($query)){
$pendingqtys[$row['townid']][$row['itemname']]=$row['pendingqty'];
}
Then to display the results
echo "<table><thead><tr><th>Town Names</th>";
foreach($itemnames as $itemname){
echo "<th>".$itemname."</th>";
}
echo "</tr></thead><tbody>";
foreach ($pendingqtys as $town => $pendingqty){
echo "<tr><th>".$town."</th>";
foreach ($itemnames as $itemname){
echo "<td>".$pendingqty[$itemname]."</td>";
}
echo "</tr>";
}
echo "</tbody></table>";

display mutidimentional array result as table

I will like to display the result of my multidimensional array in a table like this
Thank you for any help.
| product ID | Product Name | Quantity | Price
--------------------------------------------------------------------
|$item['part_id']| $product_name| $item['quantity']| $item['price']
--------------------------------------------------------------------
|$item['part_id']| $product_name| $item['quantity']| $item['price']
......
here is the result of my array
$result = mysqli_query($con, $sql );
if ($result) {
echo 'Number of item selected: ' . mysqli_affected_rows($con)."<br/>";
foreach($_SESSION["cart_array"]as $item){
$i++;
$item_id=$item['part_id'];
$sql = mysqli_query($con,"SELECT * FROM oproduct_description
WHERE product_id='$item_id' LIMIT 1");
While($row=mysqli_fetch_array($sql)){
$product_name=$row["name"];
}
echo'itemID '.$item['part_id']."";
echo'product name '.$product_name."";
echo 'item Quantity '.$item['quantity']."";
echo 'item Price '.$item['price']."<br/>";
}
}
Well instead of echoing out I would create a table array and use a function call to output the table.
$arrayVariable[] = array(
'itemID' => $item['part_id'],
'productName' => $product_name,
'itemQuantity' => $item['quantity'],
'itemPrice' => $item['price']);
function tableFunction($a){
echo '<table><tr>| product ID | Product Name | Quantity | Price</tr>';
foreach($a as $rowData){
echo "<tr>|$rowData['itemID']| $rowData['productName']| $rowData['itemQuantity']| $rowData['itemPrice']</tr>";
}
echo '</table>';
}

Categories