foreach category echo results - php

i'm attempting to list my suppliers in order, with showing the items that I need to order under the supplier. But the script originally provided to me lists the supplier each time.
This is what i've got:
$dataSQL = "SELECT * FROM inventory WHERE product_active='Y' ORDER BY product_supplier, product_category, product_code ASC";
$data = mysql_query($dataSQL) or die(mysql_error());
$rows = mysql_num_rows($data);
while($result = mysql_fetch_array( $data )) {
$category=$result['product_category'];
$id=$result['id'];
$item1=$result['product_name'];
$code1=$result['product_code'];
$code2=$result['product_suppliercode'];
$soh=$result['product_soh'];
$reorder=$result['product_reorder'];
$supplier=$result['product_supplier'];
$order=$result['product_reorder']-$result['product_soh'];
// output row from database
if($soh<$reorder) {
echo "
<tr><td>$supplier</td><td>SOH $soh | Order $order</td></tr>
<tr><td>$item1</td><td>$code1</td></tr>
";
}
}
However, if there is more than 1 product low on stock from 1 supplier, i only want to list the supplier once, not every time.
This is the current result:
Low & Out of Stock Report
Biz Supplies SOH 3 | Order 1
White Thermal Travel Mug 0000000001030
Office Works SOH 14 | Order 1
Frixion Stamp Coffee Cup (Orange) 4902505508073
Office Works SOH 0 | Order 1
Frixion Stamp Apple 4902505508103
PHE (Paper Handling Equipment) SOH | Order 1
20mm 100pk Plastic Binding Comb
(box)
0000000004115
(sorry, not sure how to display here in table format). The end result would be that it would show the supplier name once, then on the next row show the item, code, soh & reorder

You can select DISTINCT product_supplier.
So your query will become:
SELECT DISTINCT ON product_supplier *
FROM inventory
WHERE product_active='Y'
ORDER BY product_supplier, product_category, product_code ASC
Alternatively, you can use a GROUP BY on the column that you want to eliminate duplicates:
SELECT *
FROM inventory
WHERE product_active='Y'
GROYP BY product_supplier
ORDER BY product_supplier, product_category, product_code ASC

Related

Select Random yet distinct rows from table - MySQL

I have a table with various categories, and multiple entries for each category.
Word | Category
------------------
Apple | Food
Orange | Food
Grapes | Food
Mango | Food
I wish to retrieve 3 random rows for the category 'food', for which I run the following query,
$query = "SELECT * FROM table WHERE category='food' ORDER BY RAND() LIMIT 3"
$fetch_row = mysqli_query($db_connect, $query);
while ($row = mysqli_fetch_array($fetch_row)) {
array_push($words, $row['word']);
}
However, when I print the contents of the array $words, they tend to repeat sometimes (not on all runs), for example;
Apple, Orange, Apple
i.e. Its not always unique. I want to select random, yet unique words for a given category. What am I doing wrong? I've tried going through other related answers, but I keep messing something up. I've also tried the following query;
SELECT * FROM table WHERE category='food' GROUP BY category ORDER BY RAND() LIMIT 3
But this still gives repetitions occasionally.
Since word column have same values, do GROUP BY word like below:-
SELECT * FROM table WHERE category='food' GROUP BY word LIMIT 3

PHP & Mysql - nested loop

I have 2 tables - products and productimages.
product has unique id and title.
productimages has productid and imageurl. these are examples of my tables:
products:
|id|title |
_____________
|1 |Laptop |
|2 |Speakers |
productimages:
|productid|imageurl|
___________________
| 1 |lap1.png|
| 1 |lap2.png|
| 1 |lap3.png|
| 2 |spe1.png|
Right now I have a nested loop in PHP.
loop through all rows of -> select * from products
and for every product inside the loop -> select * from productimages where productid = id which is basically another loop inside the first loop.
and then I take all productimages into array and decode to JSON [title,photos].
Now imagine you have 2 million rows in productimages, the query times are too high, is there any way to make it more efficient?
$query = "SELECT * FROM products ORDER BY id LIMIT 10;
$result = mysqli_query($con,$query);
if(mysqli_num_rows($result)>0)
{
$response = array();
while($row = mysqli_fetch_assoc($result)) {
$photos = array();
$id = $row["id"];
$title = $row["title"];
$queryp = "select imageurl from productimages where productid= '".$id."';";
$resultp = mysqli_query($con,$queryp);
if(mysqli_num_rows($resultp)>0)
{
while($row2 = mysqli_fetch_assoc($resultp)) {
$photourl = $row2["imageurl"];
array_push($photos,$photourl);
}
}
}
}
Some betterment for you could be:
1) Don't use select *. Use column names instead. e.g. select products.id, products.title, productimages.imageurl
2) Use JOIN instead of nested loop
So, you can try querying data like:
select products.id, products.title, productimages.imageurl
from products
join productimages on products.id = productimages.productid
ORDER BY products.id LIMIT 10
This case is not uncommon - you have two tables in a one to many relationship.
You should never nest an SQL call in a loop if you can possibly avoid it but there is a decision to be made about one SQL call or two.
A single SQL call could be:
SELECT id, title, imageURL
FROM products LEFT JOIN productImages ON id=productid
The disadvantage of this is that you are extracting the title several times for each product and this is wasteful.
Using two SQL statements you can download the titles once for each product:
SELECT id, title FROM products
The results of this query can be stored in an associative array - so that you can look up the title for each id.
The second query is:
SELECT productid, imageURL FROM productImages ORDER BY productid, imageURL
You can loop through the results of this query, spitting out the title as you go.
To save the images with product you can add a column imageurl in the products table.collect the image names with , and insert that image name string to the products table.
your table looks like below.
+--------------+--------------+---------------------------+
| id | title | imageurl |
+--------------+--------------+---------------------------+
| 1 | Laptop | lap1.png,lap2.png,lap3.png|
+--------------+--------------+---------------------------+
| 2 | Speakers | spe1.png |
Hope you understood what i explain.

Get next and previous records within the same query

I'm having this PDO query to call data from a MySQL.
$sql = "SELECT itemName FROM furniture WHERE itemID = :item";
While calling for this particular itemName, is it possible to get the next and previous itemNames by using its itemID within this same query itself without having to write a new query to get the next and previous itemNames?
e.g.
if
itemID | itemName
___________________________
553 | Mahogani Black Chair
554 | Teak Round Table
555 | Thulang Relaxing Chair
556 | Teak Relaxing Chair
$sql = "SELECT itemName FROM furniture WHERE itemID = :item";
$stmt = $connect->prepare($sql);
$stmt->execute(array(':item'=>"554"));
$rslt = $stmt->fetchAll(PDO::FETCH_ASSOC);
I'm looking away of getting Teak Round Table and Mahogani Black Chair and Thulang Relaxing Chair
Please use this code:
(SELECT itemName FROM furniture WHERE itemID < 554 order by itemID desc limit 1)
UNION
(SELECT itemName FROM furniture WHERE itemID >= 554 order by itemID asc limit 2)
For Example code :
MyTable:
================
id Store_name
================
1 English
2 French
3 Tamil
4 Uk
5 US
<?php
$con = mysqli_connect("localhost","root","ramki","ramki");
$sql = "(SELECT store_name FROM store WHERE id < 2 order by id desc limit 1)
UNION
(SELECT store_name FROM store WHERE id >= 2 order by id asc limit 2)";
$query = mysqli_query($con,$sql);
while ($row = mysqli_fetch_assoc($query)) {
echo $row['store_name'];
echo "<br>";
}
?>
$sql = "SELECT itemName FROM furniture WHERE itemID IN (:item-1, :item, :item+1) ORDER BY itemID";
For iterating the results, you can also use PDO fetch() function to get each row.

Getting a daily summary of figures from shop database

I have the following tables, in a standard shop:
(id is always primary key, auto-increment, ts is always type TIMESTAMP, updated ON_UPDATE CURRENT_TIMESTAMP)
table sales:
id | total | tendered | flag | userID | ts
1 0.6 0.6 0 4 2013-11-21 08:12:23
Sales is the parent table, userID is related to the user that made the sale. total and tendered are both of type FLOAT. flag is of type VARCHAR and could be Free Order.
table receipts:
id | oID | pID | quantity | ts
1 1 26 1 2013-11-21 08:11:25
Receipts holds a line for each unique type of product sold. oID is type INT and relates to the id of table sales. pID is of type INT and relates to the id of table products.
table products:
id | name | price | cID | display | ts
1 Mars 0.6 3 1 2014-01-17 07:55:25
Products is the central data for each product in the database. Here is a line for mars bars. cID relates to the id in table categories.
table categories
id | name | display | ts
3 Snacks 1 2013-11-14 12:06:44
Categories is the table holding all the data about each category, and can have multiple products relating to a single row. display is of type INT and dictates when the category is enabled or disabled (1 = 'true')
My question is, I want to output information like this:
**Snacks**
(name) (quantity) (price) (total)
Fruit 3 50p £1.50
Twix 1 60p 60p
Boost 1 60 60p
**Hot Drinks**
(name) (quantity) (price) (total)
English Tea 15 60p £9.00
Speciality Teas 2 60p £1.20
Which I have the following SQL for:
SELECT categories.name AS category, products.name, pID,
(SELECT SUM(quantity) FROM receipts WHERE pID=r.pID AND DATE(ts) = CURDATE()) AS quantity,
products.price,r.ts
FROM receipts r
LEFT JOIN products ON r.pID = products.id
LEFT JOIN categories ON products.cID = categories.id
WHERE DATE(r.ts) = CURDATE()
GROUP BY r.pID
ORDER BY categories.name;
Which seems to give me the correct information, but I am not 100% certain. If anyone could verify that this works, I would be most grateful. But when I want to see a particular day, I get unusual figures with the following SQL:
$postfrom = $_POST['from_mm']."/".$_POST['from_dd']."/20".$_POST['from_yy'];
$postto = $_POST['to_mm']."/".$_POST['to_dd']."/20".$_POST['to_yy'];
$from = strtotime($postfrom . " 6:00");
$to = strtotime($postto . " 23:59");
$itemised = select("SELECT categories.name AS category, products.name, pID,
(SELECT SUM(quantity) FROM receipts WHERE pID = r.pID AND UNIX_TIMESTAMP(r.ts) > '{$from}' AND UNIX_TIMESTAMP(r.ts) < '{$to}')
AS quantity, products.price
FROM receipts r
LEFT JOIN products ON r.pID = products.id
LEFT JOIN categories ON products.cID = categories.id
WHERE UNIX_TIMESTAMP(r.ts) > '{$from}'
AND UNIX_TIMESTAMP(r.ts) < '{$to}'
GROUP BY r.pID
ORDER BY categories.name;");
(function 'select' simply returns an array of the SQL table). The thing is, I could find the results easily by looping through in PHP and adding it up that way. But I know this is possible with SQL, I just don't know why It isnt working. Can somebody please help?
Edit SQL sample fiddle is here: http://sqlfiddle.com/#!2/23af4 although I couldn't do more than half a day of data due to 8000 character restrictions.
Try this:
SELECT categories.name AS category, products.name AS name,
receipts.quantity AS quantity, products.price AS price,
(receipts.quantity * products.price) AS total
FROM categories
JOIN products
ON categories.id = products.cID
JOIN receipts
ON receipts.pID = products.ID
WHERE DATE(receipts.ts) = CURDATE()
ORDER BY categories.name
SQLFiddle demo
With regard to the date restriction, you could use BETWEEN ... AND ... to specify the date and time. Using an absolute date and time moment or relative to the current day and time, for example WHERE DATE(receipts.ts) BETWEEN concat(curdate() -5,' 6:00:00 AM') AND curdate() -4

Mysql JOIN not returning value for joined table

I cannot for the life of me figure out why I can't get image from table B. It returns nothing from table B from everything from table A.
I'm wondering if it's table structure. The way the table is set up is there could be multiple instances of order_number in the order_detail table. Both Product_id fields are INT(10) and previously the order_detail table didn't have a primary key (auto increment). Because Order Number is taken from another table and each order could have 10 of the same order number for every product purchased, the primary key is a separate field.
Should I create the order_number as an index field? Any help would be awesome b/c I'm about to give up.
Here is order details:
id order_number date_time product_id product_name quantity
2 10011 2012-12-20 14:11:24 13 T-Shirt 1
3 10011 2012-12-20 20:02:31 11 T-Shirt 1
Here is products:
product_id who product_name color size price image
13 men T-shirt red medium 15.00 /images/apparel/t-shirt.jpg
11 men T-Shirt red small 15.00 /images/apparel/t-shirt.jpg
This is the end result of my query:
Order Number Image Product Name Quantity Cost Each Total
10011 T-Shirt 2 $15.00 $30
10011 T-Shirt 2 $15.00 $30
$order_number = $_GET['var1'];
$query = "SELECT a.product_name, a.quantity, b.image, a.product_cost FROM order_detail a LEFT JOIN products b ON a.product_id = b.product_id WHERE a.order_number = '$order_number'";
$data = mysqli_query($dbc, $query);
while($row = mysqli_fetch_assoc($data)){
$prod_name = $row['product_name'];
$quantity = $row['quantity'];
$cost = $row['product_cost'];
$img = $row['image'];
It works with your data and query with some changes (there is no product_cost field in order_detail table):
http://www.sqlfiddle.com/#!2/38c9b/7

Categories