counting total within a while loop - php

In my project I am fetching data from the database using a while loop where each data is fetched by a customer id as $cid. Now all the data is calculated and finally put into a variable $cashflow. Now suppose there are 20 persons so the table will display 20 records where each data is counted for each person / customer. Now what I want to do is count the total of all 20 records and echo it seperately.
For eg.
Cust.1 : 500 (calculated from $cashflow)
Cust. 2 : 1000
Cust.3 : 800 ..... and so on.
Now these data are well echoed in my table. Now what I want is to add 500+1000+800 and echo 2300 as total separately. But I am not being able to figure out how to do it in my code. Should I take a variable in loop as a ++ counter? or something else? Please help.
Code:
$cash = "SELECT SUM(paid) FROM hbil WHERE cid = '".$cid."' AND method = 'cash'";
$cash_qur = mysql_query($cash) or die(mysql_error());
$cash_neg = "SELECT SUM(price) FROM hbil WHERE cid = '".$cid."' AND method = 'cash' AND price < 0";
$cash_qur_neg = mysql_query($cash_neg) or die(mysql_error());
while($cash_fetch = mysql_fetch_array($cash_qur))
{
$cash_fet = mysql_fetch_array($cash_qur_neg);
$cashpay = $cash_fetch['SUM(paid)'];
$cashneg = $cash_fet['SUM(price)'];
$cash_total = $cashpay-$cashneg;
$cashflow = number_format($cash_total,2,'.',',');
}

$total = 0;
while (...) {
//...
$total += $cash_total;
}
echo $total;
Will do the trick

Related

Is there a better way to run multiple SQL queries to the same table using PHP?

I have a query that requests an ID (the PK) and an order number and throws them into an array. I then loop through the returned data in the array and run two more queries to find the number of times the order number shows up in the database and to get the invoice numbers that belong to that order number. The problem I'm seeing with this setup is that it is taking a while (around 9 seconds) to return the compiled data array. Is there a faster way to get the returned results I'm looking for?
I've tried to find some articles online and came across mysqli_multi_query. Is this the better route to make multiple queries to gather the type of data I am trying to get?
<?php
require 'config.php';
$sql = "SELECT id,internal_order_number FROM orders GROUP BY internal_order_number ORDER BY created_date desc LIMIT 0 ,50";
$query=mysqli_query($mysqli, $sql);
if (!$query) {
throw new Exception(mysqli_error($mysqli)."[ $sql]");
}
$data = array();
while( $row=mysqli_fetch_array($query) ) { // preparing an array
$nestedData=array();
$nestedData['line_id'] = $row["id"];
$nestedData['internal_order_number'] = $row["internal_order_number"];
$data[] = $nestedData;
}
$compiled_data = array();
// Loop through data array with additional queries
foreach($data as $line){
$new_data = array();
// Get item counts
$item_counts = array();
$get_count = " SELECT internal_order_number FROM orders WHERE internal_order_number = '".$line['internal_order_number']."' ";
$count_query=mysqli_query($mysqli, $get_count);
while ($counts=mysqli_fetch_array($count_query)){
if (isset($item_counts[$counts['internal_order_number']])) {
$item_counts[$counts['internal_order_number']]++;
} else {
$item_counts[$counts['internal_order_number']] = 1;
}
}
$product_count = $item_counts[$line['internal_order_number']];
// Get invoice numbers
$invoice_array = array();
$get_invoices = " SELECT invoice_number FROM orders WHERE internal_order_number = '".$line['internal_order_number']."'";
$invoice_query=mysqli_query($mysqli, $get_invoices);
while ($invoice=mysqli_fetch_array($invoice_query)){
if(!in_array($invoice['invoice_number'], $invoice_array)){
$invoice_array[] = $invoice['invoice_number'];
}
}
$invoices = implode(", ",$invoice_array);
$new_data['order_number'] = $line['internal_order_number'];
$new_data['count'] = $product_count;
$new_data['invoices'] = $invoices;
$compiled_data[] = $new_data;
}
mysqli_close($mysqli);
print_r($compiled_data);
?>
What, why are you doing basically the same query 3 times. You first one selects them all, you second query requires the same table making sure the first tables order number == the tables order number and the last just grabs the invoice number...?
Just do one query:
SELECT internal_order_number, invoice_number FROM table WHERE ...
Then loop through it and do what you need. You don't need 3 queries...

PhP/MySQL: how to dynamically change my (large and always changing) database

Scenario
I have a MySQL database with 10.000 rows. Setup of the database:
ID UniqueKey Name Url Score ItemValue
1 5Zvr3 Google google.com 13 X
2 46cfG Radio radio.com -20 X
3 2fg64 Yahoo yahoo.com 5 X
.... etc etc etc
As you can see, each item has a score. The score is constantly changing. Google may have a score of 13 now, but tomorrow it may be 80, or -50.
What I want:
I want to create a system that creates a hierarchy in my current database, based on the score of the items. Right now I'm thinking about percentile ranks, meaning that the highest scoring items will be close to 100%, and the lowest scoring items will be close to 0%. For this I created some code that will try to achieve what is shown here: http://www.psychstat.missouristate.edu/introbook/sbk14m.htm
This is my code:
$sql = "SELECT * FROM database order by Score";
$result = $conn->query($sql);
$count = 0;
while ($row = $result->fetch_assoc()) {
$woow = $row['Score'];
$sql = "SELECT * FROM database WHERE Score = $woow";
$resultnew = $conn->query($sql);
$somanythesame = $resultnew->num_rows;
$itemPercentile = ( ($count/$result->num_rows + 0.5*$somanythesame/$result->num_rows) * 100 );
$rowID = $row['ID'];
$sql2 = "UPDATE database SET itemValue = $itemPercentile WHERE ID = $rowID";
$conn->query($sql2);
$count++;
}
This works, but for one problem it does not: There are many items in my database, many with the same score. To illustrate my problem, here is a very simple 10-row database with only the Scores:
Scores
-10
0
0
0
10
20
20
30
40
50
The problem with my code is that it doesn't give the same percentile for the items with the same Score, because it takes in account all previous rows for the calculation, including the ones with the same Score.
So, for the 2nd, 3rd and 4th item with a Score of 0, it should be like this: (1/10 + 0.5*1/10) * 100. Problem is, that for the 3rd item it will do (2/10 + 0.5*1/10) * 100 and the 4th item it will do (3/10 + 0.5*1/10) * 100.
Then, for the 5th item with a score of 10, it should do (4/10 + 0.5*1/10) * 100. This is going well; only not for the items with te same score.
I'm not sure if I explained this well, I find it hard to put my problem in the right words. If you have any questions, let me know! Thank you for your time :)
You need to maintain an "identical count" ($icount) variable that tracks the number of items with an identical score and a "current score" ($score) that tracks the current score.
$icount = 0;
$score = null;
Increment $icount instead of $count when $woow == $score (identical value check). Otherwise, add it to your $count and increment, and then reset the $icount value to 0.
if ($woow == $score) {
$icount++;
} else {
$count += $icount + 1;
$icount = 0;
}
Finally, set your $score value to the latest $woow for testing in the next iteration of the loop:
$score = $woow;
This will allow items with the same Score to have the same $count value, while incrementing an additional $icount times when a new $score is found.
Your final code will look like this:
$sql = "SELECT * FROM database order by Score";
$result = $conn->query($sql);
$count = 0;
$icount = 0;
$score = null;
while ($row = $result->fetch_assoc()) {
$woow = $row['Score'];
$sql = "SELECT * FROM database WHERE Score = $woow";
$resultnew = $conn->query($sql);
$somanythesame = $resultnew->num_rows;
$itemPercentile = ( ($count/$result->num_rows + 0.5*$somanythesame/$result->num_rows) * 100 );
$rowID = $row['ID'];
$sql2 = "UPDATE database SET itemValue = $itemPercentile WHERE ID = $rowID";
$conn->query($sql2);
if ($woow == $score) {
$icount++;
} else {
$count += $icount + 1;
$icount = 0;
}
$score = $woow;
}
You can change $sql query:
$sql = "SELECT *,count(*) FROM database group by Score order by Score";
In this case, you fetch score with counts and no more select needed in the while loop.
Even you can select Percentile in MySQL query:
Select t2.* , #fb as N , ((t2.fb1 + 0.5 * t2.fw)/#fb*100) as percentile from (
Select t1.* , (#fb := #fb + t1.fw) as fb1 from (
Select score,count(*) as fw From tablename group by score order by score ASC
) as t1
) as t2
I think this query returns most of columns which you may needs to check results.

Displaying 5 rows of data from query

I have a simple table (mgap_orders) with customer orders in it. Multiple have the the same id (mgap_ska_id) and I simply want to pull 5 records from the table and display all five.
I can easily get one record with the following query and PDO, but how can I display 5 rows instead of only one row?
$result_cat_item = "SELECT * FROM mgap_orders WHERE mgap_ska_id = '$id' GROUP BY mgap_ska_id";
while($row_cat_sub = $stmt_cat_item->fetch(PDO::FETCH_ASSOC))
{
$item=$row_cat_sub['mgap_item_description'];
$item_num=$row_cat_sub['mgap_item_number'];
$item_type=$row_cat_sub['mgap_item_type'];
$item_cat=$row_cat_sub['mgap_item_catalog_number'];
$item_ven=$row_cat_sub['mgap_item_vendor'];
$item_pur=$row_cat_sub['mgap_item_percent_purchased'];
$item_sales=$row_cat_sub['mgap_item_sales'];
}
Use limit 5 then put the results in an array, like this:
$result_cat_item = "SELECT * FROM mgap_orders WHERE mgap_ska_id = '$id' GROUP BY mgap_ska_id LIMIT 5";
$items = array();
while($row_cat_sub = $stmt_cat_item->fetch(PDO::FETCH_ASSOC))
{
$items['item'] = $row_cat_sub['mgap_item_description'];
$items['item_num'] = $row_cat_sub['mgap_item_number'];
$items['item_type'] = $row_cat_sub['mgap_item_type'];
$items['item_cat'] = $row_cat_sub['mgap_item_catalog_number'];
$items['item_ven'] = $row_cat_sub['mgap_item_vendor'];
$items['item_pur'] = $row_cat_sub['mgap_item_percent_purchased'];
$items['item_sales'] = $row_cat_sub['mgap_item_sales'];
}
Then you can do:
foreach($items as $item) {
// echo $item['item'] or whatever
}
EDIT: Or you can skip putting them in the array and just use the while() to do what you need to do with the data.

Trouble sending various queries into proper rows for set times

sorry about the title, i really did not know what I should call it, but hopefully you will be able to aid me with my script.
What I am trying to achieve (with my less than 5 hour total experience with any sort of "programming", hence the horrid coding) is to send one query X times, and then put a new query into those newly created rows.
if(isset($_SESSION['email'])) { // IF LOGGED IN
$sql = mysql_query("SELECT max(ordrenr) FROM antalstabel") or die(mysql_error());
$maxordrenr = mysql_query($sql);
$nextnumber = $maxordrenr + 1;
$maxplusantal = $maxordrenr + $antal;
$antal = count($items); // COUNTS DIFFERENT ITEMS IN CART.
for ($i = $maxordrenr; $i <= $maxplusantal; $i++) {
$sql = mysql_query("INSERT INTO antalstabel (ordrenr) VALUES ('$nextnumber')") or die(mysql_error());
}
}
This is my first query, what this does (or what I want it to do) is to get the max ID of the table "antalstabel" add +1 and then count a certain amount up which is defined as $items untill it has executed X rows.
My first issue here, is the fact that my table consists of two key primaries, so returning a query like this would result in an error since after one return the two rows would be identical and will not execute.
The second issue is the fact that the next value in the table should not be inserted X times after each other, but rather be certain IDs added in afterwards.
What I am trying to achieve ultimately (not only by this script, but this is the current issue) is something like this:
ordrenr(key)varenr(key) antal
1 3 1
1 2 2
2 1 4
3 1 1
3 2 1
3 3 1
Does this make any sense whatsoever for anyone and can anyone tell me whether my method of doing this is jsut hopeless or have some better ideas for me to use as execution for ending up with something like this?
Should I not use primary keys or how does this work?
Thank you for even taking the time to read this :)
-Victor
EDIT for future:
changed script to this for it to work:
if(isset($_SESSION['email'])) { // IF LOGGED IN
$sql = mysql_query("SELECT * FROM antalstabel ORDER BY ordrenr DESC LIMIT 1") or die(mysql_error());
$row = mysql_fetch_assoc($sql);
$maxordrenr = $row['ordrenr'];
$nextnumber = $maxordrenr + 1;
$maxplusantal = $maxordrenr + $antal;
$antal = count($items); // COUNTS DIFFERENT ITEMS IN CART.
for ($i = $maxordrenr; $i <= $maxplusantal; $i++) {
$sql = mysql_query("INSERT INTO antalstabel (ordrenr, varenr) VALUES ('$nextnumber','1236')") or die(mysql_error());
}
$maxordrenr = mysql_query($sql);
should be
$maxordrenr = mysql_result($sql,0);

Total up how many men and how many women in a column. Possibly in order to repopulate the planet

Trying to search through a column in a db, and pull out the total number of males, and total number of females.
This data is stored in the db as f and m in the whatsex column.
$query = "SELECT whatsex, COUNT(*) FROM soberdata GROUP BY whatsex";
$result = mysqli_query($connection,$query) or die(mysql_error());
$sexdb = mysqli_fetch_array($result);
$totalmale = $sexdb['m'];
$totalfemale = $sexdb['f'];
echo $totalfemale." & ".$totalmale;
This code outputs nothing. What am I doing wrong?
$sexdb have only "whatsex" and "COUNT(*)" columns. You should use one of them
try
print_r($sexdb);
and look if some of results meet your needs
Your query is going to return a whatsex value, and a COUNT(*) value, not m or f. Doing a var_dump($sexdb) would show you what's in the array.
You are treating a multi-dimensional array as flat. You could do this to flatten it
$query = "SELECT whatsex, COUNT(*) as total FROM soberdata GROUP BY whatsex";
while ($row = mysqli_fetch_array($result)) {
$$row['whatsex'] = $row['total']; // this makes a variable ($m or $f) using the value of the row
}
$totalmale = !empty($m) ? $m : 0;
$totalfemale = !empty($f) ? $f : 0;
You should empty check the results of the db in case there is no male or female entries to avoid errors.

Categories