Sum values in each group with a loop - php

I have a while loop that gives this result:
Userid Point
1 10
1 15
2 5
2 10
3 8
3 2
How can I sum the userid points and output with highest number first, like this:
Userid Point
1 25
2 20
3 10
Is there any "foreach", "for" or any other method that can accomplish such result?
The code:
include ('variables.php');
//Fetch data from matchdata table
$q = "SELECT userid, matchid, homescore, awayscore FROM predictiondata ORDER BY userid ASC";
$r = mysqli_query($mysqli, $q);
while ($row = mysqli_fetch_array($r)) {
//Define predictions
$predhome = $row['homescore'];
$predaway = $row['awayscore'];
//Fetch gameresults
$qres = "SELECT id, homescore, awayscore, bonuspoints FROM matches WHERE id = ".$row['matchid']."";
$rres = mysqli_query($mysqli, $qres);
$result = mysqli_fetch_array($rres);
$homescore = $result['homescore'];
$awayscore = $result['awayscore'];
$bonus = $result['bonuspoints'];
$id = $result['id'];
//Calculate points
if ($homescore == $predhome && $awayscore == $predaway && $homescore != '') { $result_point = $correct_score + $correct_result + $correct_number + $correct_number; }
else if ($homescore == $predhome && $awayscore != $predaway OR $homescore != $predhome && $awayscore == $predaway) { $result_point = $correct_result + $correct_number; }
else if ($predhome > $predaway && $homescore > $awayscore OR $predhome < $predaway && $homescore < $awayscore) { $result_point = $correct_result; }
else if (is_null($predhome) OR $homescore == '') { $result_point = 0; }
else { $result_point = 0; }
if ($homescore == $predhome && $awayscore == $predaway && $homescore != '') { $bonus = $bonus; }
else if (is_null($predhome) OR $homescore == '') { $bonus = 0; }
else { $bonus = 0; }
if (is_null($predhome) OR $homescore == '') { $total_point = 0; }
else { $total_point = $result_point + $bonus; }
//Calculate total round sum
$total_roundsum = $result_point + $bonus;
//echo $username.' - '.$total_roundsum.'<br />';
if($total_roundsum != 0) {
echo $row['userid']. ' - ' .$total_roundsum.'<br />';
}
}
At the moment, the code only echo's the results.
The "variables.php" holds the $correct_score + $correct_result + $correct_number variables.

Assuming the two columns are an associated array -- $users_and_points.
$points_array = array();
foreach ( $users_and_points as $user_id => $point ) {
if( !isset( $points_array[$user_id] ) {
$points_array[$user_id] = 0;
}
$points_array[$user_id] += $point;
}
// newly associated array with calculated totals
$points_array;
Update
Based on your code above instead of echoing build an array of users and points.
echo $row['userid']. ' - ' .$total_roundsum.'<br />';
can be replaced with:
if( !isset( $points_array[$row['userid']] ) {
$points_array[$row['userid']] = 0;
}
$points_array[$row['userid']] += $total_roundsum;
That will give you an associated array of user ids and associated points.
print_r( $points_array );
Note: Set the variable before your loop. Example, $points_array = array();

Related

How to get the label in the result of an array

The following code works as expected to get the number of patients per age group.
It also gets the highest (or most common) age group.
$count_0_19 = 0;
$count_20_29 = 0;
$count_30_39 = 0;
$count_40_49 = 0;
$count_50_59 = 0;
$count_above_60 = 0;
$curr_year = date('Y');
$sql= "SELECT pt_dob FROM ptlist WHERE mid=$userID";
$stmt = $pdo->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$result = $pdo->query($sql);
$pt_dob = $row[ 'pt_dob' ];
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
$pt_dob = explode('-', $row['pt_dob']);
$year = $pt_dob[0];
$month = $pt_dob[1];
$day = $pt_dob
$temp = abs($curr_year - $year);
if($temp >= 0 && $temp <= 19) {
$count_0_19++;
}
elseif($temp >= 20 && $temp <= 29) {
$count_20_29++;
}
elseif($temp >= 30 && $temp <= 39) {
$count_30_39++;
}
elseif($temp >= 40 && $temp <= 49) {
$count_40_49++;
}
elseif($temp >= 50 && $temp <= 59) {
$count_50_59++;
}
else {
$count_above_60++;
}
}
echo '0-19: '.$count_0_19.'<br>';
echo '20-29: '.$count_20_29.'<br>';
echo '30-39: '.$count_30_39.'<br>';
echo '40-49: '.$count_40_49.'<br>'; // example output is > 40-49: 7 (i.e. 7 patients in age group 40-49)
echo '50-59: '.$count_50_59.'<br>';
echo '60+: '.$count_above_60.'<br>';
// getting highest value
$a = array($count_0_19, $count_20_29, $count_30_39, $count_40_49, $count_50_59, $count_above_60);
$res = 0;
foreach($a as $v) {
if($res < $v)
$res = $v;
}
echo $res;
^^ This tells me that e.g. 9 patients are in the 30-39 age group - i.e. the highest number of patients are in this age group.
But $res gives me only the number (e.g. 9).
What I am asking your help with is to get $res to give me the text(or label) "30-39", instead of the number 9.
Please help.
continue from comment... you need to store $key into a variable.
$a = array('0-19'=>$count_0_19, '20-29'=>$count_20_29, '30-39'=>$count_30_39, '40-49'=>$count_40_49, '50-59'=>$count_50_59, '60+'=>$count_above_60);
$res = 0;
$label = '';
foreach($a as $key => $v) {
if($res < $v){
$res = $v;
$label = $key; //get label from key and store in a variable
}
}
echo 'label = '.$label . ' , Number = '.$res;
You can archived this by creating the array of labels and then incrementing it according and then find the greatest value form the $label array to get the key.
$label = [
"0_19" => 0,
"20_29" => 0,
"30_39" => 0,
"40_49" => 0,
"50_59" => 0,
"above_60" => 0,
];
while ($row4 = $result4->fetch(PDO::FETCH_ASSOC)) {
$pt_dob = explode('-', $row4['pt_dob']);
$year = $pt_dob[0];
$month = $pt_dob[1];
$day = $pt_dob$temp = abs($curr_year - $year);
if ($temp >= 0 && $temp <= 19) {
$label['0_19'] = $label['0_19'] +1;
}
elseif ($temp >= 20 && $temp <= 29) {
$label['20_29'] = $label['20_29'] +1;
}
elseif ($temp >= 30 && $temp <= 39) {
$label['30_39'] = $label['30_39']+1;
}
elseif ($temp >= 40 && $temp <= 49) {
$label['40_49'] = $label['40_49'] +1;
}
elseif ($temp >= 50 && $temp <= 59) {
$label['50_59'] = $label['50_59']+1;
}
else {
$label['above_60']= $label['above_60']+1;
}
}
echo $maxs = array_keys($label, max($label));
echo "<br/>";
foreach($label as $k => $v);
echo "key $k count $v <br/>";

Can I have more than one while(!feof) loop in a program?

If I'm trying to display a table (which I've accomplished with a while loop) but also display a count underneath it. Do I add another while loop? Or a seperate for loop? How would I do that? I need to count the number of performances (Ive got that working) but it wont tally the number of performances in Asheville. How do I target that variable by itself?
> <?php print ("<h1>Upcoming Performances in 2015</h1>"); print
> ("<table border =\"1\">"); print("<tr><th align =
> \"left\">Date</th><th align = \"left\">Venue</th><th align =
> \"left\">City</th><th align = \"right\">Ticket Price</th></tr>");
>
> $count = 0; $ashevilleCount = 0; $eventFile =
> fopen("performances.txt", "r"); $schedule = fgets($eventFile);
>
>
> while(!feof($eventFile)) { list($date, $venue, $city, $ticketPrice) = explode(":", $schedule);
> print("<tr><td>$date</td>"); print("<td>$venue</td>"); print("<td>$city</td>"); print("<td>$ticketPrice</td>");
> $schedule = fgets($eventFile);
> }
>
> for($count = 1; $count <= 5; $count = $count + 1) { $total = fgets($eventFile); $count = $count + $total;
> }
> if ($city == Asheville)
> $ashevilleCount = $ashevilleCount + $count;
>
>
>
>
>
> fclose($eventFile);
> print ("</table>");
>
> print ( "<p class=\"alert\">Lower cost venues are marked with
> *</p>"); print ("<p>NUMBER OF PERFORMANCES: $count</p>"); print ("<p>NUMBER OF PERFORMANCES IN ASHEVILLE: $ashevilleCount</p>");
>
>
>
>
> ?>
You need to take a look at your if statements.
if($condition === true){
//executes if $condition is true
} elseif($condition === 1) {
//executes if $condition is 1
} elseif($condition === 2 || $condition === 3){
//executes if $condition is 2 OR condition is 3
} elseif($condition === 4 && $otherCondition !== "foo"){
//executes if $condition is 4 AND $otherCondition is NOT "foo"
} else {
//executes if no other statements are true
}
This piece of code:
elseif
($charType == human or dwarf and $goldSpent <= 10)
$supplyTokens = $_POST['supplyTokens'] + 10;
Needs to look like:
} elseif( ( $charType=="human" || $charType=="dwarf" ) && $goldSpent <= 10) {
$supplyTokens = $_POST['supplyTokens'] + 10;
}
Remember:
|| = "or"
&& = "and"
test != "test" - make sure your strings are enclosed in quotation marks
See:
http://php.net/manual/en/control-structures.if.php
http://php.net/manual/en/control-structures.elseif.php
http://php.net/manual/en/language.operators.comparison.php
Here's your code cleaned up. What was done:
Changed all the print() commands to concatenated echos.
Fixed the conditionals
You don't need to check for $goldSpent <= 10 in your elseifs as you have already checked that by not being in $goldSpent > 10
I personally prefer || and && as opposed to or and and
Added curly brackets {}
Thing to consider:
What would happen if any of those $_POST values are empty??
<?php
$charName = $_POST['charName'];
$charType = $_POST['charType'];
$healthTokens = $_POST['healthTokens'];
$expTokens = $_POST['expTokens'];
$supplyTokens = $_POST['supplyTokens'];
$goldSpent = $healthTokens / 10 + $expTokens / 2 + $supplyTokens / 25;
if ($goldSpent > 10) {
echo "<h1>HEY THERE, $charName!</h1>" .
"<p>YOU SPENT MORE GOLD THAN YOU HAVE!</p>" .
"<p>GO BACK AND TRY THAT AGAIN - YOU HAVE 10 GOLD PIECES..</p>";
} elseif ($charType == 'elf') {
$healthTokens = $_POST['healthTokens'] + 5;
} elseif ($charType == 'wizard') {
$expTokens = $_POST['expTokens'] + 2;
} elseif ($charType == 'human' || $charType == 'dwarf') {
$supplyTokens = $_POST['supplyTokens'] + 10;
}
$totalGold = 10;
$goldLeft = $totalGold - $goldSpent;
echo "<h1>You have created $charName the $charType!</h1>" .
"<p>$charName has <strong>$healthTokens</strong> health tokens," .
"<strong>$expTokens</strong> experience tokens, and" .
"<strong>$supplyTokens</strong> supply tokens.</p>" .
"<p>You received some bonus tokens! :)</p>" .
"<p>$charName has spent <strong>$goldSpent</strong> gold pieces, " .
"and has <strong>$goldLeft</strong> gold pieces left.</p>";

php while loop if to do for first row else to do for second row?

I have while loop from mysql , i try to do some thing for first result under if else do other thing for second result etc....
my code this
$i = 1;
while($row = mysql_fetch_array($get_row)) {
$rowid = $row['rowid'];
$number = $row['number'];
$result = $number - 1;
if ($result != '0') {
// for only first result != 0 do this
require('result.php');
$i++;
// for all other results != 0 too do this
$edit_row = "UPDATE rows SET status = 'Ok' WHERE rowid = '$rowid'";
mysql_query($edit_row);
} elseif ($result == '0') {
$edit_row = "UPDATE rows SET status = 'Not Ok' WHERE rowid = '$rowid'";
mysql_query($edit_row);
}
}
Simply can use $i by increasing it. Do for first row when $i == 1 else do other. Example:
$i = 1;
while($row = mysql_fetch_array($get_row)) {
$rowid = $row['rowid'];
if ($i == 1) { //Do for first row when $i == 0
$i++; //Increase the value of $i
require('result.php');
$edit_row = "UPDATE rows SET status = 'Ok' WHERE rowid = '$rowid'";
mysql_query($edit_row);
} else { //Do other when $i > 1
$edit_row = "UPDATE rows SET status = 'Not Ok' WHERE rowid = '$rowid'";
mysql_query($edit_row);
}
}
Also suggest you to use mysqli or PDO instead mysql.

MySQL Join Queries

I've been given this code to work with, and I know that mysql_* is deprecated, but I'm trying to figure out a way to join all of these queries, because these while loops and queries are hogging resources and killing load time. Any suggestions?
$result2 = mysql_query("SELECT * FROM tblOperators WHERE (Team = 'SALES' OR Team = 'RENEWALS' OR Team = 'CSR') AND OperatorLocale='USA' AND OperatorStatus='ACTIVE'");
while ($row2 = mysql_fetch_array($result2)) {
$operID = $row2['OperatorID'];
$result = mysql_query("SELECT * FROM tblUserPayments WHERE OperatorID = '$operID' AND PaymentStatus='OK' AND PaymentDate LIKE '$currentDate%'");
while ($row = mysql_fetch_array($result)) {
if ($row['PaymentReason'] == 'ACTIVATION') {
$ActvCount++;
if ($row['PaymentMethod'] == 'CREDITCARD' || $row['PaymentMethod'] == 'PAPERCHECK') {
$ActvUpgrade += $row['ChargeAmount'];
}
} elseif ($row['PaymentReason'] == 'UPGRADE') {
$userid = $row['UserID'];
$paymentdate = $row['PaymentDate'];
$result1 = mysql_query("SELECT * FROM tblRenewalInvoices WHERE UserID='$userid' AND ('$paymentdate' >= DATE_SUB(DueDate, INTERVAL 90 DAY) AND '$paymentdate' < DATE_ADD(DueDate, INTERVAL 15 DAY)) AND ParentInvoiceID IS NULL ORDER BY InvoiceNum DESC LIMIT 1");
if ($row1 = mysql_fetch_array($result1)) {
$packageid = $row['PackageID'];
$pack = mysql_query("SELECT * FROM tblUserPackages WHERE PackageID='$packageid';");
if ($pack1 = mysql_fetch_array($pack)) {
$expDate = $pack1['ExpirationDate'];
$dueDate = $row1['DueDate'];
$days = mysql_fetch_row(mysql_query("SELECT TO_DAYS('$expDate')-TO_DAYS('$dueDate');"));
$months = (int) (((int) $days + 14) / 30.4);
$years = (int) (((int) $days + 182) / 365);
$Intervals = 0;
if ($years > 0) {
$Intervals = $years;
} if (($pack1['Package'] or 'GPS-SVL') or ($pack1['Package'] == 'GPS-1') or ($pack1['Package'] == 'GPS-1PLUS')) {
if ($Intervals > 1) {
if ($row['PaymentMethod'] == 'CREDITCARD' || $row['PaymentMethod'] == 'PAPERCHECK') {
$renewalCount++;
$Actv += $row['ChargeAmount'];
}
} else {
if ($row['PaymentMethod'] == 'CREDITCARD' || $row['PaymentMethod'] == 'PAPERCHECK') {
$renewalCount++;
$ActvRenewal += $row['ChargeAmount'];
}
}
} else {
$renewalCount++;
$Actv += $row['ChargeAmount'];
}
} else {
}
} else {
if ($row['PaymentMethod'] == 'CREDITCARD' || $row['PaymentMethod'] == 'PAPERCHECK')
$ActvUpgrade += $row['ChargeAmount'];
}
} elseif ($row['PaymentReason'] == 'ADDVEHICLE') {
if ($row['PaymentMethod'] == 'CREDITCARD' || $row['PaymentMethod'] == 'PAPERCHECK')
$ActvVehicleAdds += $row['ChargeAmount'];
}
}
$result = mysql_query("SELECT * FROM tblRenewalCalls WHERE OperatorID = '$operID' AND PayStatus='OK' AND DateSubmitted LIKE '$currentDate%'");
while ($row = mysql_fetch_array($result)) {
if ($row['Charged']) {
if ((int) $row['RenewYears'] > 1) {
$renewalCount++;
$Actv += $row['RenewTotal'];
} else {
$renewalCount++;
$ActvRenewal += $row['RenewTotal'];
}
}
}
} if ($ActvCount != 0) {
$PerActv = ($ActvUpgrade + $ActvVehicleAdds) / $ActvCount;
} else {
$PerActv = 0;
}
$total = $Actv + $ActvRenewal + $ActvUpgrade + $ActvVehicleAdds;
// Fix to show proper renewal dollars
$ActvRenewal = $total - ($ActvVehicleAdds + $ActvUpgrade);
$AvgRenewal = ($ActvRenewal) / $renewalCount;
$upgradeEarned = $ActvUpgrade;
$renewalEarned = $ActvRenewal;
Here is my code so far for the joined query, but it's not correct because I am still missing certain bits of information. It is much faster for mysql to handle the mathematics, than for the database to pass the information to php, then have php process it. I'm just not sure as to how to approach this:
$result = mysql_query(
"SELECT p.PaymentReason AS PaymentReason,
p.PaymentMethod AS PaymentMethod,
p.ChargeAmount AS ChargeAmount,
p.UserID AS UserID,
p.PaymentDate AS PaymentDate,
r.PackageID AS PackageID
FROM tblOperators AS o JOIN tblUserPayments AS p JOIN tblRenewalInvoices
AS r JOIN tblUserPackages AS k JOIN tblRenewalCalls
AS c ON o.OperatorID=p.OperatorID
AND r.UserID=p.UserID AND r.PaymentDate=p.PaymentDate
AND r.PackageID=k.PackageID
WHERE (o.Team='SALES' OR o.Team='RENEWALS' OR o.Team='CSR') AND
o.OperatorLocale='USA' AND
o.OperatorStatus='ACTIVE' AND
p.PaymentStatus='OK' AND
p.PaymentDate LIKE '$currentDate%'");
Any help is greatly appreciated.
Try this:: You have missed the JOIN Criteria for Table tblRenewalCalls
SELECT p.PaymentReason AS PaymentReason,
p.PaymentMethod AS PaymentMethod,
p.ChargeAmount AS ChargeAmount,
p.UserID AS UserID,
p.PaymentDate AS PaymentDate,
r.PackageID AS PackageID
FROM tblOperators AS o
JOIN tblUserPayments AS p ON o.OperatorID=p.OperatorID
JOIN tblRenewalInvoices AS r ON r.UserID=p.UserID AND r.PaymentDate=p.PaymentDate
JOIN tblUserPackages AS k ON r.PackageID=k.PackageID
JOIN tblRenewalCalls AS c // JOIN CRITERIA
WHERE (o.Team='SALES' OR o.Team='RENEWALS' OR o.Team='CSR') AND
o.OperatorLocale='USA' AND
o.OperatorStatus='ACTIVE' AND
p.PaymentStatus='OK' AND
p.PaymentDate LIKE '$currentDate%'")

Wrong Standard Deviation result in PHP

I have a problem with calculating the standard deviation in php. But it's generating the wrong result.
e.g. I am getting as result for (4+4+4+4+4+4) = 1.40 instead of 0.
Please help.
function std_dev ($attr, $test1,$test2,$test3,$test4,$test5,$test6) {
//$items = array($test1->$attr,$test2->$attr,$test3->$attr,$test4->$attr,$test5->$attr,$test6->$attr);
$items[] = array();
if (isset($test1) && $test1->$attr != 9 && $test1->$attr != 0) {
$items[] = $test1->$attr;
}
if (isset($test2) && $test2->$attr != 9 && $test2->$attr != 0) {
$items[] = $test2->$attr;
}
if (isset($test3) && $test3->$attr != 9 && $test3->$attr != 0) {
$items[] = $test3->$attr;
}
if (isset($test4) && $test4->$attr != 9 && $test4->$attr != 0) {
$items[] = $test4->$attr;
}
if (isset($test5) && $test5->$attr != 9 && $test5->$attr != 0) {
$items[] = $test5->$attr;
}
if (isset($test6) && $test6->$attr != 9 && $test6->$attr != 0) {
$items[] = $test6->$attr;
}
$sample_square[] = array();
$item_count = count($items);
for ($current = 1; $item_count > $current; ++$current) $sample_square[$current] = pow($items[$current], 2);
$standard_deviation = sqrt(array_sum($sample_square) / $item_count - pow((array_sum($items) / $item_count), 2));
return round($standard_deviation,2);
}
$items = array();
$sample_square = array();
no [] when you define those variables as arrays.
for ($current = 0; $item_count > $current; ++$current)
start from 0 not 1 if you want to iterate over all the elements (otherwise you'll miss item at index 0)
Wondering what this is for...
if (isset($test1) && $test1->$attr != 9 && $test1->$attr != 0) {
$items[] = $test1->$attr;
}
and how you pass input values to the function. This may also cause wrong result...

Categories