Combining multiple MySQL queries into 1 - php

I am trying to display a summary table which is currently using multiple MySQL queries and I was wondering if it's possible to combine them into one.
I have a table called 'payments' with the fields amount and currency, and i'm trying to display a summary totals table for each of the currencies. As an example:
<table>
<tr>
<td>USD</td>
<td>EUR</td>
<td>GBP</td>
</tr>
<tr>
<? $q1 = mysqli_query("SELECT sum(amount) as total_USD from payments WHERE currency='USD'");
while($row1 = mysqli_fetch_assoc($q1)){ ?>
<td><? echo number_format($row1['total_USD'],0); ?></td>
<? } ?>
<? $q2 = mysqli_query("SELECT sum(amount) as total_EUR from payments WHERE currency='EUR'");
while($row2 = mysqli_fetch_assoc($q2)){ ?>
<td><? echo number_format($row2['total_EUR'],0); ?></td>
<? } ?>
<? $q3 = mysqli_query("SELECT sum(amount) as total_GBP from payments WHERE currency='GBP'");
while($row3 = mysqli_fetch_assoc($q3)){ ?>
<td><? echo number_format($row3['total_GBP'],0); ?></td>
<? } ?>
</tr>
</table>
In reality, I am using 12 currencies so I have 12 separate queries but it feels inefficient so I was wondering if there is an easier way to achieve the same result?
Many thanks!

SELECT currency,
SUM(amount) as total
FROM payments
GROUP BY currency

Solution 1:
SELECT currency, SUM(amount) as total FROM payments GROUP BY currency
Solution 2 :
$currencies=array(USD,EUR,GBP,...);
foreach($currencies as $currency){
$q1= mysqli_query("SELECT sum(amount) as total from payments WHERE currency='".$currency."'");
while($row1 = mysqli_fetch_assoc($q1)){
echo number_format($row1['total'],0);
}
}

You can use a GROUP BY here.
SELECT currency, SUM(amount) as total FROM payments GROUP BY currency
http://dev.mysql.com/doc/refman/5.1/en/group-by-modifiers.html

Related

Returns all rows with Minimum Value in Php

I have a table that consist of records and i want to retrieve rows with minimum price. I try the code below, and i am only able to retrieve only one rows. i need to return all rows with minimum price for the same partno.
<tr>
<th>S/N</th>
<th>Part Number</th>
<th>Description </th>
<th nowrap="nowrap">Recommended Price</th>
<th nowrap="nowrap">Recommended Supplier</th>
</tr>
<?php
$get = mysqli_query($con,"SELECT MIN(price)As price,partno,supplier,description FROM tab_stockqty2 ");
$c=0;
while($rw = mysqli_fetch_array($get)){
$c++;?>
<tr>
<td nowrap="nowrap"><?php echo $c;?></td>
<td nowrap="nowrap"><?php echo $rw['partno'];?></td>
<td nowrap="nowrap"><?php echo $rw['description'];?></td>
<td><?php echo number_format($rw['price'],2);?></td>
<td><?php echo $rw['supplier'];?></td>
</tr>
<?php };?>
See Database Record:
It show return two rows, but it is only retuning only one row for the first set of partno-2070081
To retrieve all records with minimal price, per partno, the query should be something like this:
SELECT s.price,s.partno,s.supplier,s.description FROM tab_stockqty2 s
INNER JOIN (
SELECT MIN(price) as m, partno FROM tab_stockqty2 GROUP BY 2
) m on s.price = m.m and s.partno = m.partno
Demo: http://sqlfiddle.com/#!9/3e089/1
try this ==>
SELECT MIN(price)As price,partno,supplier,description FROM tab_stockqty2 group by partno
The SQL MIN returns only 1 row which is the most minimum.
What you can do is fetch all records and sort them on price based on ascending order.
SELECT price,partno,supplier,description FROM tab_stockqty2 ORDER BY price ASC;
Try this instead.
In this way you will get records based on price from Low to High.

Count column of table group by rows

I can count number of a table rows by using mysqli_num_rows. I have a table which contains similar rows. How can I count by grouping by similar row?
For instance: I have a table with 2 columns : Student and Option. Let say there are 50 students. 20 are in Economy option, 20 are in Management option and 10 are in Secretary Option. How can display those numbers. I can display only the 50.
my codes
$qry = "select * from table group by option";
$req= #mysqli_query($conn, $qry);
$result = mysqli_query( $conn, "select id from table");
$num_rows = mysqli_num_rows($result);
Students Total (<?php echo $num_rows ?>)
<table >
<tr>
<th>Student</th>
<th>Option</th>
</tr>
<?php
while($row=mysqli_fetch_array($req))
{
?>
<tr>
<td><?php echo $row['student'] ?></td>
<td><?php echo $row['option'] ?></td>
</tr>
<?php
}
?>
</table>
Here is the query you need:
SELECT COUNT(*) AS `option_count`, * -- returns a count aliased as "options_count"
FROM `table`
GROUP BY `option` -- will group the options and show the counts
Now you can echo the count, along with other data:
echo $row['count_options'];
echo $['options'];
The problem that you have here is that you will not be able to display each student in the option because this counts / groups only the three options.
Behold the proper query :
$qry = "select option as opt, COUNT(*) AS option from table group by option";

Query for printing two same products as a single product on receipt?

I am developing point of sale in php.I have two different sales . I sold 4 mobiles in first sale and sold 2 mobiles in second sale.The following query prints 2 items on receipt.But i want to display only one item(mobile) with quantity 6??
<?php
$result = $db->query("SELECT * FROM stock_sales where date BETWEEN '$fromdate' AND '$todate' ");
while ($line = $db->fetchNextObject($result)) {
?>
<tr>
<td><?php echo $line->stock_name; ?><
<td><?php echo $line->quantity; ?></td>
</tr>}
Modify your query to be
SELECT stock_name, count(*), sum(quantity) AS sum_quantity FROM stock_sales where date BETWEEN '$fromdate' AND '$todate' group by stock_name

How can I limit the display to distinct records?

As shown in the picture below, there are redundant records. How can the redundancy be removed?
Here's my code:
<?php
$YearNow=Date('Y');
include('../connection/connect.php');
$result = $db->prepare("SELECT * FROM studentvotes,student where student.idno = studentvotes.idno");
$result->execute();
for($i=0; $row = $result->fetch(); $i++){
?>
<tr class="record" style="text-align:center;">
<td><?php echo $row['idno']; ?></td>
<td><?php echo $row['candid']; ?></td>
</tr>
<?php
}
?>
You need to use GROUP BY.
Change your SQL To:
SELECT * FROM studentvotes,student where student.idno = studentvotes.idno
GROUP BY student.idno
With GROUP BY, you specify a column (even multiple columns) to group with.
The results are grouped by those columns it means those columns (combinations if multiple) will come only once in the result set.
For example, your table has multiple entries of iDno.
When we fire SELECT query, it will return all rows having multiple instances of iDno.
If we apply GROUP BY, it will return results grouped by iDno.
just add groupby to your query like
$result = $db->prepare("SELECT * FROM
studentvotes,student
where student.idno = studentvotes.idno
GROUP BY student.idno
");
for more details please read #pupil Answer.
i hope this is working for you.
You can use GROUP BY for not displaying redundant records.
$result = $db->prepare("SELECT *
FROM studentvotes,
student
WHERE student.idno = studentvotes.idno
GROUP BY student.idno
");

How to display combined rows in the database table with same ID

i have a question for the experts. I have no idea how to combine all the order ID with the same ID,
like in the picture, all orders with order ID = 1 are in one transaction, how do i combine all order IDs with the same id and display only one total price for all of the proudcts bought. and since all order ID are the same so the deliver and payment option will also be the same just need to display one row.
and a follow up question is how will i also show all the products bought if i combine all the same order IDs, compute the total price and display delivery and payment option in one single row
Here is the picture for my database relationship, i just followed the ones on the internet. the only difference is that "products" are changed to "inventory" and "serial" in products are changed to "prod_id"
here are my codes to display the current picture.
<?php
session_start();
$conn = #mysql_connect("localhost","root","");
$db = #mysql_select_db("");
$qry = "SELECT customers.name,customers.payment,customers.carrier, orders.date, order_detail.productid, order_detail.quantity, order_detail.price, order_detail.orderid, inventory.prod_name
FROM customers
RIGHT JOIN orders on customers.serial=orders.serial
RIGHT JOIN order_detail on orders.serial=order_detail.orderid
LEFT JOIN inventory on order_detail.productid=inventory.prod_id where customers.email='{$_SESSION['email']}'";
mysql_set_charset("UTF8");
$result = #mysql_query($qry);
if($result === FALSE) {
die(mysql_error()); // TODO: better error handling
}
echo "<center>";
echo "<table class='CSSTableGenerator'>
<tr>
<td>Date of Purchase</td>
<td>First Name</td>
<td>Order ID</td>
<td>Products</td>
<td>Quantity</td>
<td>Total Price</td>
<td>Delivery Option</td>
<td>Payment Option</td>
<tr>";
while ($row=mysql_fetch_array($result)){
echo "<tr>";
echo "<td>".$row['date']."</td>";
echo "<td>".$row['name']."</td>";
echo "<td>".$row['orderid']."</td>";
echo "<td>".$row['prod_name']."</td>";
echo "<td>".$row['quantity']."</td>";
echo "<td>".($row['price']*$row['quantity'])."</td>";
echo "<td>".$row['carrier']."</td>";
echo "<td>".$row['payment']."</td>";
echo "</tr>";
}
echo "</table>";
?>
</table>
It seems that what you're needing to learn for this particular question is the SQL Group By clause.
This (untested, might need minor tweaking) should do the trick. Note that you don't get order item quantities out of this, but I would say that it's possible to get them.
SELECT o.date, c.name, o.serial as 'Order Id', GROUP_CONCAT(p.name) as 'Products', SUM(od.price) as 'Total', c.carrier, c.payment
FROM orders o
JOIN customers c on o.customer_id = c.serial
JOIN orderdetail od on o.serial = od.orderid
JOIN products p on od.productid = products.prod_id
GROUP BY o.serial
Of particular note is a handy aggregate function in MySQL called GROUP_CONCAT.
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

Categories