I have data coming back from MySQL and the goal is to pull data from multiple servers.
The data can be grouped by one or more fields, and I want to pull data from X number of MySQL servers and sum the data that should be summed, using the other data as a key or index.
Example:
Result from Mysql[$x]:
[{"date":"2017-10-10","account":"1","trees":"1","people":"0","pets":"4"}
,{"date":"2017-10-10","account":"2","trees":"2","people":"5","pets":"1"}
,{"date":"2017-10-11","account":"1","trees":"3","people":"3","pets":"4"}
,{"date":"2017-10-11","account":"2","trees":"4","people":"1","pets":"4"}]
Result from Mysql[$x+1]:
[{"date":"2017-10-10","account":"1","trees":"5","people":"1","pets":"1"}
,{"date":"2017-10-10","account":"2","trees":"5","people":"2","pets":"1"}
,{"date":"2017-10-11","account":"1","trees":"5","people":"0","pets":"2"}
,{"date":"2017-10-11","account":"2","trees":"5","people":"1","pets":"2"}]
Desired end result:
[{"date":"2017-10-10","account":"1","trees":"6","people":"1","pets":"5"}
,{"date":"2017-10-10","account":"2","trees":"7","people":"7","pets":"2"}
,{"date":"2017-10-11","account":"1","trees":"8","people":"3","pets":"6"}
,{"date":"2017-10-11","account":"2","trees":"9","people":"2","pets":"6"}]
in this case, there are 2 keys, date and account, but in reality there can be between 1 and 4.
The grouping keys are known, so the code knows that in this case, date and account are the keys.
I'm trying to find a better way than iterating through each row of mysql[$x] and then iterating through each row of mysql[$x+1] ... mysql[$x+n] and checking each value of the known keys to see if they match the current row's key values and then summing the data.
Also note that in reality, there may not be a row for each set of keys, hence the number and order of rows from each server can be variable.
I need an efficient way to do this because there are potentially tens of thousands of rows with a dozen+ columns.
I'm experimenting with code like this:
$res = array();
$keys = array('date','account');
array_walk($t,'rehash',$res);
function rehash($data,$key,&$result) {
global $keys;
global $res;
$keydata = array_slice($data,0,count($keys));
$vals = array_slice($data,count($keys));
//this is how the data would ideally be structured, my model
//$res[$keydata[$keys[0]]][$keydata[$keys[1]]] = $vals;
//this code below successfully creates rows in the right format
for($x = count($keys) - 1; $x>= 0; $x--) {
if($x == count($keys)-1) {
$tmp = array($keydata[$keys[$x]] => $vals);
//} else if($x ==0) {
// maybe reconcile here?
} else {
$tmp = array($keydata[$keys[$x]] => $tmp);
}
}
}
But how do i reconcile this? I can't simply do $res[key1] = $tmp[key1] because with multiple keys it would remove all the other rows.
Also with nested arrays, how would I iterate through each nested array if the number of levels is variable?
Lastly if I do this, I would need to convert it back into the original format for the frontend, so... joy. :D (this part would be easy, just is worth taking into consideration from an efficiency standpoint)
You don't need to use array_walk, since your data isn't hierarchical. Just use an ordinary foreach loop.
$res = array();
foreach ($t as $row) {
$cur = &$res;
// Drill down into result array using the key fields, creating nested arrays
// as necessary
foreach ($keys as $keycol) {
$key = $row[$keycol];
if (!isset($cur[$key])) {
$cur[$key] = array();
}
$cur = &$cur[$key];
}
// Now go through the data columns in the row, adding them to the totals
foreach ($row as $key => $val) {
if (in_array($key, $keys)) {
// Put the key fields in the result row
$cur[$key] = $val;
} else {
// Accumulate other values in the result row
if (!isset($cur[$key])) {
$cur[$key] = 0;
}
$cur[$key] += $row[$key];
}
}
unset($cur); // Break the reference link
}
Here is a possible solution based on the structure of the sample data given in the question.
$jsn1 = '[{"date":"2017-10-10","account":"1","trees":"1","people":"0","pets":"4"}
,{"date":"2017-10-10","account":"2","trees":"2","people":"5","pets":"1"}
,{"date":"2017-10-11","account":"1","trees":"3","people":"3","pets":"4"}
,{"date":"2017-10-11","account":"2","trees":"4","people":"1","pets":"4"}]';
$jsn2 = '[{"date":"2017-10-10","account":"1","trees":"5","people":"1","pets":"1"}
,{"date":"2017-10-10","account":"2","trees":"5","people":"2","pets":"1"}
,{"date":"2017-10-11","account":"1","trees":"5","people":"0","pets":"2"}
,{"date":"2017-10-11","account":"2","trees":"5","people":"1","pets":"2"}]';
/* Decode the json strings into associative arrays: */
$arr1 = json_decode($jsn1, true);
$arr2 = json_decode($jsn2, true);
/* Put in an array the keys whose values are to be added: */
/* Do not include date and account keys if they are not to be added */
$arr_keys = ['trees', 'people', 'pets'];
/* Loop through both $arr1 and $arr2 while storing new arrays in arr: */
/* Be adding up the values for the keys that are in $arr_keys */
$arr = [];
foreach($arr1 as $k => $v){
$arr[$k]['date'] = $arr1[$k]['date']; $arr[$k]['account'] = $arr1[$k]['account'];
foreach($arr_keys as $y){
if($arr1[$k][$y] !== null && $arr2[$k][$y] !== null){
$arr[$k][$y] = $arr1[$k][$y] + $arr2[$k][$y];
}}}
/* encode the array to the required json string: */
$json = json_encode($arr);
echo $json;
/* Output:
[{"date":"2017-10-10","account":"1","trees":"6","people":"1","pets":"5"}
,{"date":"2017-10-10","account":"2","trees":"7","people":"7","pets":"2"}
,{"date":"2017-10-11","account":"1","trees":"8","people":"3","pets":"6"}
,{"date":"2017-10-11","account":"2","trees":"9","people":"2","pets":"6"}]
*/
$runrwos = array();
for ($i = 0; $runrwos= mysql_fetch_assoc($run); $i++)
{
$DD_E_SC[$i]=$runrwos['DD_E_SC'];
$DD_E_pKW[$i]=$runrwos['DD_E_pKW'];
$DD_G_SC[$i]=$runrwos['DD_G_SC'];
$DD_G_pKW[$i]=$runrwos['DD_G_pKW'];
$data[$i] = array('DD_E_SC'=>$runrwos['DD_E_SC'],'DD_E_pKW'=>$runrwos['DD_E_pKW'], 'DD_G_SC'=>$runrwos['DD_G_SC'], 'DD_G_pKW'=>$runrwos['DD_G_pKW']);
foreach ($data as $entry)
{
$Ep =($entry['DD_E_SC']*365+$entry['DD_E_pKW']*$SE_cons )/100;
$Gp =($entry['DD_G_SC']*365+$entry['DD_G_pKW']*$SG_cons )/100;
$Tp=$Ep+$Gp;
}
}
I have the above code that get row data from a database, once data are retrieved and stored into an array give the expected result.
This code work fine, but output result as retrieved from database.
My problem is when I sort the data by $Tp or $Ep or $Gp.
I need to sort by descendant or ascendant value.
Any help Thanks
i have a mysql table the contains an index id, a data entry and 10 other columns called peso1, peso2, peso3...peso10. im trying to get the last 7 peso1 values for a specific id.
like:
$sql = mysql_query("SELECT * FROM table WHERE id='$id_a' ORDER BY data DESC LIMIT 0, 7");
when i try to fetch those values with mysql_fetch_array, i get all values together.
example:
while($line = mysql_fetch_array($sql)) {
echo $line['peso1'];
}
i get all peso1 values from all 7 days together. How can i get it separated?
They will appear all together because you are not separating them as you loop through them.
for example, insert a line break and you will see them on separate lines
while($line = mysql_fetch_array($sql)) {
echo $line['peso1'] ."<br />";
}
You could key it as an array like so
$myArray = array();
$i = 1;
while($line = mysql_fetch_array($sql)) {
$myArray['day'.$i] = $line['peso1'];
$i++;
}
Example use
$myArray['day1'] // returns day one value
$myArray['day2'] // returns day two value
It's not clear what you mean by "separated" so I'm going to assume you want the values as an array. Simply push each row field that you want within your while loop onto an array like this:
$arr = array();
while($line = mysql_fetch_array($sql)) {
$arr[]=$line['peso1'];
}
print_r($arr);//will show your peso1 values as individual array elements
I have one array which have the right order of the keys,
For example,
$array_keysorder=([0]=>"Fire",[1]=>"Sky",[2]=>"Third")
//Array i want to sort,after appending the order is messed up
$tosortarray=(['Sky']=>array(array()...),['Third']=>array(),['Fire']=>array())
//This is how i want the final array to look like
$Final=(['Fire']=>array(), ['Sky']=>array(array()...),['Third']=>array())
What about rebuilding the array?
Edit.. I added some commenting..
<?php
$array_keysorder[] = "Fire";
$array_keysorder[] = "Sky";
$array_keysorder[] = "Third";
print_r($array_keysorder);
$bad_array[Sky] = "data1";
$bad_array[Third] = "data2";
$bad_array[Fire] = "data3";
echo "<br>";
print_r($bad_array);
//This count cycles through the sort order, 0 = Fire, 1 = Sky, etc.
$key = 0;
//Cycle through array. $row isn't used.
foreach($bad_array as $row)
{
//$temp_val will store the key name ie "Fire".
$temp_val = $array_keysorder[$key];
//Create a organized array with the correct order of the keys
$good_array[$temp_val] = $bad_array[$temp_val];
//Increase the key to the next one.
$key++;
}
echo "<br>";
print_r($good_array);
?>
What I want to do here is to be able to assign the values from sql query into arrays.
And then compute for the total.
<?php
include('conn.php');
$qreports=query_database("SELECT S_PRICE, PID, QTY_PUR, ITEM_ID, CUSID, CNUM, Cust_Name, TDATE FROM prod_table, customer_credit, sales_trans_items WHERE prod_table.PID=sales_trans_items.ITEM_ID AND sales_trans_items.CNUM=customer_credit.CUSID AND sales_trans_items.TDATE='2011-02-06 09:14:09'","onstor",$link);
$grandtotal=0;
$customer="";
while($qrep=mysql_fetch_assoc($qreports)){
$pid=$qrep['PID'];
foreach ($pid as $k => $v) {
$sids=$v;
$qtypur=$qrep['QTY_PUR'][$k];
$sprice=$qrep['S_PRICE'][$k];
$customer=$qrep['Cust_Name'][$k];
$tdate=$qrep['TDATE'][$k];
$stot=$qtypur * $sprice;
$grandtotal =$grandtotal + $stot;
}
}
echo "Customer: ". $customer."<br/>";
echo "Profit: ". $grandtotal;
?>
I tried the query on phpmyadmin before I place it in the code, and it output this:
I think you misunderstood how mysql_fetch_assoc works: Every call returns one row from the result set. $grep is an array with structure columnname => value.
That also means that $qrep['PID'] cannot be an array and your foreach loop won't work. In every loop, $qrep['PID'] contains one of the values you see in the PID column in your screen shot.
I suggest you add print_r($qreq); in your while loop so you get more familiar with the structure of the array.
As each $qrep is an array itself, creating a result array is just adding each of these to a new array:
$result = array();
while(($qrep=mysql_fetch_assoc($qreports))) {
$result[] = $qrep;
}
Now you are performing some more computation where I am not sure what you want to get in the end but it seems you are multiplying each QTY_P with S_PRICE:
$total = 0;
foreach($result as $report) {
$total += $report['QTY_P'] * $report['S_PRICE'];
}
(You could however also compute this in your while loop)
Assuming you want to get the overall sum and the sum for each customer:
$total = 0;
$total_per_customer = array();
foreach($result as $report) {
$customer = $report['Cust_Name'];
if(!array_key_exists($customer, $total_per_customer)) {
$total_per_customer[$customer] = 0;
}
$price = $report['QTY_P'] * $report['S_PRICE'];
$total_per_customer[$customer] += $price;
$total += $price;
}
In the end, $total_per_customer is an array with customer names as keys and the sum of the prices as values. $total will contain the sum of all prices.
You question is a bit unclear, but i think the answer wont be far a way from the following suggested references:
As you loop through the rows use
something like $array[] =
$qrep['columnName'] to populate an
array.
Then, check out PHP's array_sum().