How to calculate a running total? - php

I have looked at the other (many closed) running total questions in PHP however none satisfy
This is my query
<?php
$query = "SELECT SUM(game_total) AS totalgames,
SUM(goals) AS totalgoals,
FROM player
WHERE year between 2006 and 2013
AND month between 1 and 12
GROUP BY
year,
month between 1 and 3,
month between 4 and 6,
month between 7 and 9,
month between 10 and 12
ORDER BY year ASC, month ASC";
$rquery = mysql_query($query) or die(mysql_error());
$show2 = '';
while ($row = mysql_fetch_array($rquery)){
$games = $row['totalgames'];
$goals = $row['totalgoals'];
$gpg = $games == 0 ? 0 : number_format($goals/$games,2);
}
?>
If I echo the results of the query completing the loop I get the following result
+---------+----------+-----------+
| Goals | Games | GPG |
+---------+----------+-----------+
| 8 | 15 | 0.53 |
+---------+----------+-----------+
| 2 | 12 | 0.17 |
+---------+----------+-----------+
| 2 | 12 | 0.17 |
+---------+----------+-----------+
| 13 | 21 | 0.62 |
+---------+----------+-----------+
etc etc
However, I want to calculate a running GPG in the following manner
Goals/Games=GPG
8/15=0.53
10/27=0.37 (8+2/15+12)=GPG
12/39=0.31 (10+2/27+12)=GPG
25/60=0.41 (12+13/39+21)=GPG
and I want to echo it like this
0.53,0.37,0.31,0.41 etc etc
how would I do this?

$count = 0;
while ($row = mysql_fetch_array($rquery)){
$count++;
$games = (int)$row['totalgames'];
$goals = (int)$row['totalgoals'];
$totalGames = 0;
$totalGoals = 0;
$totalGames += $goalData['games'];
$totalGoals += $goalData['goals'];
echo $totalGoals/$totalGames;
echo ($count === mysql_num_rows($rquery)-1) '' : ',';
}
There we go, running total GPG as it iterates, commas separated without making an extra array. That what you're looking for?

Related

Group Array items in PHP

I have the above array:
| Student First Name |Student Last Name | Age |Disability|
| Student_First_Name_1 |Student_Last_Name_1 | 30 | 1 |
| Student_First_Name_2 |Student_Last_Name_2 | 28 | 0 |
| Student_First_Name_3 |Student_Last_Name_3 | 21 | 0 |
| Student_First_Name_4 |Student_Last_Name_4 | 20 | 1 |
| Student_First_Name_5 |Student_Last_Name_5 | 22 | 0 |
and I want to grouped the students by age and Disability.
So if my code runs correctly I'll have the above results:
Student_First_Name_1 : Student_First_Name_4
Student_First_Name_3 : Student_First_Name_5
Student_First_Name_2
But instead I have the above:
Student_First_Name_1 : Student_First_Name_4
Student_First_Name_3 : Student_First_Name_5
Student_First_Name_2 : Student_Last_Name_3
Student_First_Name_2 : Student_Last_Name_5
My code is:
$StudentsForSID = $conn->prepare("SELECT * FROM members WHERE sid = :sid AND level = :level");
$StudentsForSID->execute([ 'sid' => $SelectedSID, 'level' => 'LRN_B1' ]);
while($row = $StudentsForSID->fetch(PDO::FETCH_ASSOC)){
$TempSelected[] = $row;
}
$count=count($TempSelected);
for($i=0; $i<$count-1; $i++){
for ($j = $i+1; $j < $count; $j++) {
if($TempSelected[$i]['disability']==$TempSelected[$j]['disability']){
if( abs($TempSelected[$i]['age']-$TempSelected[$j]['age']) <= 23 ){
$Student1 = $TempSelected[$j]['first_name'];
$Student2 = $TempSelected[$i]['first_name'];
print_r($Student1.'-'.$Student2.'<br/>');
}
}
}
}
I don't think I explained very well. So i edit the question.
What I want:
I want to make groups of 2 students with the same value in disability and the age difference between the 2 students to be equal or under 23.
So I have the above array with 5 students. From this array I'll make 3 groups and the groups will be the above (2 groups with 2 students with fulfilled the criteria, and 1 group with one student).
Can you help me?
Thank you
Why don't you use a double group by in your query?
Group by Age , Disability
This will actually group your results into two groups like you wanted so you will save the php sorting and those multiple if and for.

PHP: foreach loop by id and month and add values

I've been trying to solve this issue I'm currently having. We have a table with id, productid, userid, count and downloaddate. Something like below to understand the structure and what the results look like.
+----+-----------+--------+-------+---------------+
| id | productid | userid | count | downloaddate |
+----+-----------+--------+-------+---------------+
| 1 | 9 | 231 | 2 | October 2017 |
| 2 | 8 | 230 | 1 | October 2017 |
| 3 | 9 | 287 | 1 | October 2017 |
| 4 | 9 | 200 | 2 | November 2017 |
+----+-----------+--------+-------+---------------+
So what I want to loop is to get all the productid and return the total number of count for the given month which is recorded in the downloaddate column.
To return this:
+------------+-------+---------------+
| productid | count | downloaddate |
+------------+-------+---------------+
| 9 | 3 | October 2017 |
| 8 | 1 | October 2017 |
| 9 | 2 | November 2017 |
+------------+-------+---------------+
Is it possible to do this? I've tried this but it's returning the total count for the productid
$sum = array();
$emparray = array();
foreach ($downloads as $download){
$emparray[] = $download;
}
foreach ($emparray as $downloaded){
if (!isset($sum[$downloaded->id])) {
$sum[$downloaded->id]['count'] = $downloaded->count;
$sum[$downloaded->id]['downloaddate'] = $downloaded->downloaddate;
} else {
$sum[$downloaded->id]['count'] += $downloaded->count;
$sum[$downloaded->id]['downloaddate'] = $downloaded->downloaddate;
}
}
Any help will be appreciated!
EDIT
This is my sql query:
$downloads = $wpdb->get_results(
"
SELECT ast.*, dl.userid, dl.count, dl.downloaddate
FROM $lead_table as ast
JOIN $table_downloads as dl ON (dl.productid = ast.id)
"
);
You can get the result by one query grouping by productid and downloaddate (I hope that October2017 is a typo in the question)
SELECT productid, sum(count) as count, downloaddate
FROM your_table
GROUP BY productid, downloaddate
update. with your query it seems to be
SELECT ast.*, dl.userid, sum(dl.count) as count, dl.downloaddate
FROM $lead_table as ast
JOIN $table_downloads as dl
ON (dl.productid = ast.id)
GROUP BY dl.userid, dl.downloaddate
i think you should edit your sql Query into this :
SELECT productid, sum(count) as count, downloaddate FROM your_table GROUP BY downloaddate
You have to be able to tell which month is given in the downloaddate (can you build a timestamp ? Or something else that tells you that "October2017" is the same that "October 2017".
Once you got that, you "just" have to store your "sum" in a 2D array with something like that:
$sum = array();
foreach ($downloads as $download) {
// dateToTimeStamp: custom function who gives you the same number for October2017 or October 2017
$timestamp = dateToTimeStamp($downloaded->downloaddate);
if (!isset($sum[$timestamp])) {
$sum[$timestamp] = [];
}
if (!isset($sum[$timestamp][$downloaded->id])) {
$sum[$timestamp][$downloaded->id]['count'] = $downloaded->count;
$sum[$timestamp][$downloaded->id]['downloaddate'] = $downloaded->downloaddate;
continue 1;
}
$sum[$timestamp][$downloaded->id]['count'] += $downloaded->count;
$sum[$timestamp][$downloaded->id]['downloaddate'] = $downloaded->downloaddate;
}
you can easily use this query and extract the data from php and use it there
select productid,sum(count),downloaddate from tablename group by productid,downloaddate

Merge first column that has the same second column

I have an INNER JOIN query that returns this result:
first column | second column
2 | 15
5 | 16
6 | 16
5 | 18
6 | 22
I want to output them in my page like this:
first column | second column
2 | 15
5,6 | 16
| 18
| 22
Total first column: 2
It will combine the first column that has the same second column. And value of the combined first column will be share between them.
And would also tell the total first column (which in the example is 2).
I'm still trying with this code:
if($stmt = $con->prepare("SELECT firsttb.firstcolumn, secondtb.secondcolumn FROM firsttb INNER JOIN secondtb ON firsttb.connectid = secondtb.connectid WHERE firsttb.getid = ? ORDER BY secondtb.secondcolumn")){
$stmt->bind_param("i",$_GET["getid"]);
$stmt->execute();
$stmt->bind_result($firstcolumn,$secondcolumn);
$lastid = 0;
$total = 0;
$combine = "";
while($stmt->fetch()){
if($lastid == $secondcolumn){
$combine = $combine."".$firstcolumn;
$lastid = $secondcolumn;
}
else {
$totalrow = $totalrow + 1;
$lastid = $secondcolumn;
$combine = $secondcolumn;
echo $combine." | ".$secondcolumn."<br>";
}
}
$stmt->close();
echo "Total first column: ".$totalrow;
}
But only get this output:
first column | second column
2 | 15
5 | 16
5 | 18
6 | 22
Total first column: 4
It is okay to scrap my code and create it with your own. Just want to look for the right idea.

update table from array with different values where empty field

I have problem with my code, problem is data not update still NULL.
table A
year | period | code | user_id
2013 | 4 | 1231 |
2013 | 4 | 1232 |
2013 | 4 | 1233 |
2013 | 4 | 1234 |
2013 | 4 | 1235 |
Table B
user_id | user_name | cash
A1 | AB | 10
A2 | BC | 5
A3 | CD | 7
I will put table B user_id to table A user_id when cash >= 7
Table Result
year | period | code | user_id
2013 | 4 | 1231 | 10
2013 | 4 | 1232 | 7
2013 | 4 | 1233 |
2013 | 4 | 1234 |
2013 | 4 | 1235 |
here my code,
$arr = array();
$query = mysql_query("select user_id from tableB where cash >= 7");
while ($arrs = mysql_fetch_array($query)) {
$arr[] = $arrs[0];
}
$count = count($arr);
for ($i = 0; $i < $count; $i++) {
$sql = mysql_query("UPDATE tableA SET user_id ='$arr[$i]' WHERE year = 2013 and period = 4 and user_id IS NULL");
}
if ($sql) {
echo "success";
}
The operator in the query should be >= and not =>
check on this:
$arr[] = $arrs[0];
this now holds the first record of the result set. Expected that there is only one record with cash >= 7, that might be ok, but thats a risky assumption.
for ($i = 0; $i < $count; $i++) {
$sql = mysql_query("UPDATE tableA SET user_id ='$arr[$i]' WHERE year = 2013 and
period = 4 and user_id IS NULL");
}
in here $arr[$i] iterates over the fields of the first record, giving you in a sequence the values 'A3', 'CD' and 7 and you are running three useless updates on your table. Afterwards the column user_id in Table A has the value 7 and not 'A3' since this is the last value in your loop.
I have solution for my code,
$arr = array();
$query = mysql_query("select user_id from tableB where cash >= 7");
while ($arrs = mysql_fetch_array($query)) {
$arr[] = $arrs[0];
}
$q = mysql_query("select code from tableA order by code");
$index = 0;
while($codes = mysql_fetch_row($q)){
$sql = mysql_query("UPDATE tableA SET user_id ='".$arr[$index++]."' WHERE code='".$codes[0]."'");
}
result perfect !
thanks all

MySQL: applying a random sort on multiple columns

In order to have a well scrambled table (for a psychological experiment), I'd like to sort each column of my array by RAND().
Althrough this code works:
SELECT Sort.Variable1, Sort.Variable2 FROM Sort ORDER BY Variable1, Variable2 ASC LIMIT 0 , 30
replacing "ASC" by "RAND()" make the query fail. Can someone give me an advice (even a solution with PHP) ?
Thanks
Edit:
Thanks to all your responses, I finally did it. Here's my PHP code for this (and sorry for the old-fashioned-not-brand-new-PDO-queries). Even if it's maybe useless, I post it:
$i=0;
//Describe to retrieve variables' names
$sqlCol= 'DESCRIBE Sort';
$sqlCol= mysql_query($sqlCol);
while ($res=mysql_fetch_array($sqlCol)) {
$var[$i]=$res['Field'];
$i++;
}
$NbCol=mysql_num_rows($sqlCol); //Number of column to shuffle
// Number of items for each column
$sqlCount= 'SELECT COUNT(*) FROM Sort';
$req2= mysql_query($sqlCount) or die ('Err');
$NbLignes= mysql_result($req2,0,0) or die ();//Number of rows
//Data array
$sql= "SELECT * FROM Sort";
$req= mysql_query($sql) or die ('Err');
$sort=mysql_fetch_array($req);
for($i=0;$i<$NbCol;$i++) {
${'sql'.$i}='SELECT * FROM Sort ORDER BY RAND()';
${'input'.$i} = mysql_query(${'sql'.$i});
while(${'array'.$i}=mysql_fetch_array(${'input'.$i})) {
$bigArray[$i][]=${'array'.$i}[$i];
}
}
for($i=0;$i<$NbLignes;$i++) {
echo '<div id="q'.$i.'"style="margin-bottom: 50px; float:left">Question '.($i+1);
echo '<ul id="sortable'.$i.'" class="sortable">';
for($j=0;$j<$NbCol;$j++) {
echo '<li class="ui-state-default" id="'.$var[$j].$i.'" name="'.$var[$j].$i.'">'. $bigArray[$j][$i].'</li>';
}
echo '</ul></div>';
}
Using ORDER BY RAND() won't randomize columns - it will randomize rows.
To randomize each column separately in SQL you can:
create a result set for each column separately
randomize the order of each of them
join the columns by row number
Unfortunately the MySQL development team haven't yet implemented ROW_NUMBER which would have made this task easy, but you can workaround it by simulating ROW_NUMBER using variables:
SELECT
Column1,
Column2
FROM
(
SELECT Column1, #rn1 := #rn1 + 1 AS rank
FROM Table1, (SELECT #rn1 := 0) vars
) T1
JOIN
(
SELECT Column2, #rn2 := #rn2 + 1 AS rank
FROM Table1, (SELECT #rn2 := 0) vars
ORDER BY RAND()
) T2
ON T1.rank = T2.rank
Here is one possible method to do what you want using PHP. In the example code, I generate a list of numbers and place them in an array. You will need to grab the list from your database.
<?php
// Create 20 rows.
$rows = 20;
// Create an empty array to hold sorted values.
$sort = array();
// Fill the array with ascending/descending numbers.
for ($i = 0; $i < $rows; $i++) {
$sort[$i]['var1'] = $i + 1;
$sort[$i]['var2'] = $rows - $i;
}
// Display the sorted array.
print "Sorted:\n";
print_rows($sort);
// Here's where the important bit happens:
// Create two arrays, each containing a list of the
// array keys from the sorted array (one for each column).
$var1 = array_keys($sort);
$var2 = array_keys($sort);
// Shuffle each list or array keys (one for each column).
shuffle($var1);
shuffle($var2);
// Create an empty array to hold shuffled values.
$shuffle = array();
// For every row in the list of shuffled keys, get
// the matching value from the sorted array, and
// place it in the shuffled array.
for ($i = 0; $i < $rows; $i++) {
$shuffle[$i]['var1'] = $sort[$var1[$i]]['var1'];
$shuffle[$i]['var2'] = $sort[$var2[$i]]['var2'];
}
// Display the shuffled array.
print "\nShuffled:\n";
print_rows($shuffle);
function print_rows($array) {
print "Row | Var 1 | Var2\n";
print "------------------\n";
foreach ($array as $key=>$row) {
printf("%3d | %5d | %4d\n", $key, $row['var1'], $row['var2']);
}
}
?>
Here's the output:
Sorted:
Row | Var 1 | Var2
------------------
0 | 1 | 20
1 | 2 | 19
2 | 3 | 18
3 | 4 | 17
4 | 5 | 16
5 | 6 | 15
6 | 7 | 14
7 | 8 | 13
8 | 9 | 12
9 | 10 | 11
10 | 11 | 10
11 | 12 | 9
12 | 13 | 8
13 | 14 | 7
14 | 15 | 6
15 | 16 | 5
16 | 17 | 4
17 | 18 | 3
18 | 19 | 2
19 | 20 | 1
Shuffled:
Row | Var 1 | Var2
------------------
0 | 8 | 2
1 | 19 | 12
2 | 14 | 5
3 | 16 | 17
4 | 2 | 8
5 | 11 | 4
6 | 7 | 11
7 | 9 | 10
8 | 12 | 1
9 | 5 | 9
10 | 13 | 20
11 | 10 | 6
12 | 17 | 19
13 | 18 | 18
14 | 4 | 14
15 | 20 | 7
16 | 3 | 16
17 | 15 | 15
18 | 6 | 3
19 | 1 | 13
The code is a bit rough and ready. I'm sure there are a number of ways in which it could be improved. For example, you could change it so the it is able to handle a variable number of columns. However, the basic idea is there.
Edit:
Here's a tidied up version of the code, which will handle a variable number of columns:
// Here's where the important bit happens:
// Create an empty array to hold shuffled values.
$shuffle = array();
// Get the name of each column (key) in the array.
foreach (array_keys($sort[0]) as $col) {
// Create an array of keys containing a list of the
// array keys from the sorted array.
$keys = array_keys($sort);
// Shuffle each list or array keys.
shuffle($keys);
// For every row in the list of shuffled keys, get
// the matching value from the sorted array, and
// place it in the shuffled array.
for ($i = 0; $i < $rows; $i++) {
$shuffle[$i][$col] = $sort[$keys[$i]][$col];
}
}
// Display the shuffled array.
print "\nShuffled:\n";
print_rows($shuffle);
You can do by 2 SQL statments:
SELECT Sort.Variable1 FROM Sort ORDER BY RAND(), Variable1 LIMIT 0 , 30
SELECT Sort.Variable2 FROM Sort ORDER BY RAND(), Variable2 LIMIT 0 , 30
if you need random in PHP array use: [array_rand][1]
<?php
// load all table values in array i just set them
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
$rand_keys = array_rand($input, 2);
echo $input[$rand_keys[0]] . "\n";
echo $input[$rand_keys[1]] . "\n";
?>

Categories