get unique value from array and sum totals - php

From this Array() I want to grab the values of amount_total, shipping and partner and total them up by specific partner. So for example the partner=>2665 should have a amount_total of 41.79 + 55.95 and so on please help. I don't want to do it through SQL because I need the data as it is as well.
Array
(
[0] => Array
(
[amount_total] => 41.79
[amount_shipping] => 4.99
[amount_partner] => 14.8
[partner] => 2665
)
[1] => Array
(
[amount_total] => 55.95
[amount_shipping] => 19.96
[amount_partner] => 11
[partner] => 2665
)
[2] => Array
(
[amount_total] => 51.96
[amount_shipping] => 7.98
[amount_partner] => 23.98
[partner] => 51754
)
[3] => Array
(
[amount_total] => 24.55
[amount_shipping] => 4.99
[amount_partner] => 5.67
[partner] => 11513
)
)

You could use PHP to achieve this, but this won't be necessary.
The database can do this much more efficiently
I assume your current query looks something like this
SELECT
`amount_total`,
`amount_shipping`,
`amount_partner`,
`partner`
FROM
`salesLeads`
WHERE
[..]
MySQL gives you nice aggregate functions like SUM you can use with GROUP BY
SELECT
SUM( `amount_total` ) AS `amount_total`,
SUM( `amount_shipping` ) AS `amount_shipping`,
SUM( `amount_partner` ) AS `amount_partner`.
`partner`
FROM
`salesLeads`
WHERE
[..]
GROUP BY
`partner`
in your PHP script you access this the same way but it has the final numbers grouped and summarized by partner already
e.g.
if ($result = $mysqli->query($query)) {
while ($row = $result->fetch_assoc()) {
print_r( $row );
}
$result->close();
}
EDIT
Because you wanted a PHP solution, which again is more efficient than querying twice:
$partnerSums = array();
while ( $row = $result->fetch_assoc() ) {
if ( !array_key_exists( $row['partner'], $partnerSums ) {
$partnerSums[$row['partner']] = $row;
} else {
$partnerSums[$row['partner']]['amount_total'] += $row['amount_total'];
$partnerSums[$row['partner']]['amount_shipping'] += $row['amount_shipping'];
$partnerSums[$row['partner']]['amount_partner'] += $row['amount_partner'];
}
}
print_r( $partnerSums );

I think looping through this array and storing the totals in new array, along with checking in_array (more here) should be sufficient. All you need to do is every time you loop through an element, check if it's already in new array, and if it is - perform necessary mathematical operation

I would suggest something like this:
$res['totals']=array();
foreach($result as $res)
{
$partner = $result['partner'];
$res['totals'][$partner]+=$result['total_amount'];
}
This way you get all the data you need in just one place: the partner array '$res'.
Hope it helps you.

Related

How can I restructure this array to condense the data into a more usable format in PHP?

I will try to explain the data I'm working with first, then I'll explain what I hope to do with the data, then I'll explain what I've tried so far. Hopefully someone can point me in the right direction.
What I'm working with:
I have an array containing survey responses. The first two items are the two answers for the first question and responses contains the number of people who selected those answers. The last three items are the three answers for the other question we asked.
Array
(
[0] => Array
(
[survey_id] => 123456789
[question_text] => Have you made any changes in how you use our product this year?
[d_answer_text] => No
[responses] => 92
)
[1] => Array
(
[survey_id] => 123456789
[question_text] => Have you made any changes in how you use our product this year?
[answer_text] => Yes
[responses] => 30
)
[2] => Array
(
[survey_id] => 123456789
[question_text] => How would you describe your interaction with our staff compared to prior years?
[answer_text] => Less Positive
[responses] => 14
)
[3] => Array
(
[survey_id] => 123456789
[question_text] => How would you describe your interaction with our staff compared to prior years?
[answer_text] => More Positive
[responses] => 35
)
[4] => Array
(
[survey_id] => 123456789
[question_text] => How would you describe your interaction with our staff compared to prior years?
[answer_text] => No Change
[responses] => 72
)
)
What I want to achieve:
I want to create an array where the question_text is used as the key (or I might grab the question_id and use it instead), use the answer_text as a key, with the responses as the value. It would look something like this:
Array
(
[Have you made any changes in how you use our product this year?] => Array
(
[No] => 92
[Yes] => 30
)
[How would you describe your interaction with our staff compared to prior years?] => Array
(
[Less Positive] => 14
[More Positive] => 35
[No Change] => 72
)
)
Here's what I've tried:
$response_array = array();
foreach($result_array as $value){
//$responses_array['Our question'] = array('answer 1'=>responses,'answer 2'=>responses);
$responses_array[$value['question_text']] = array($value['answer_text']=>$value['responses']);
}
This does not work because each loop will overwrite the value for $responses_array[$question]. This makes sense to me and I understand why it won't work.
My next thought was to try using array_merge().
$responses_array = array();
foreach($result as $value){
$question_text = $value['question_text'];
$answer_text = $value['answer_text'];
$responses = $value['responses'];
$responses_array[$question_text] = array_merge(array($responses_array[$question_text],$answer_text=>$responses));
}
I guess my logic was wrong because it looks like the array is nesting too much.
Array
(
[Have you made any changes in how you use our product this year?] => Array
(
[0] => Array
(
[0] =>
[No] => 92
)
[Yes] => 30
)
My problem with array_merge is that I don't have access to all answers for the question in each iteration of the foreach loop.
I want to design this in a way that allows it to scale up if we introduce more questions with different numbers of answers. How can this be solved?
Sounds like a reduce job
$response_array = array_reduce($result_array, function($carry, $item) {
$carry[$item['question_text']][$item['answer_text']] = $item['responses'];
return $carry;
}, []);
Demo ~ https://eval.in/687264
Update
Remove condition (see #Phil comment)
I think you are looking for something like that :
$output = [];
for($i = 0; $i < count($array); $i++) {
$output[$array[$i]['question_text']] [$array[$i]['answer_text']]= $array[$i]['responses'];
}
print_r($output);
Slightly different approach than the answer posted, more in tune with what you'v already tried. Try This:
$responses_array = array();
$sub_array = array();
$index = $result[0]['question_text'];
foreach($result as $value){
$question_text = $value['question_text'];
$answer_text = $value['answer_text'];
$responses = $value['responses'];
if (strcmp($index, $question_text) == 0) {
$sub_array[$answer_text] = $responses;
} else {
$index = $question_text;
$responses_array[$index] = $sub_array;
$sub_array = array();
}
}
Edit: Found my mistake, updated my answer slightly, hopefully this will work.
Edit 2: Working with example here: https://eval.in/687275

Is it bad practice to execute this query in a for or foreach-loop?

So I have the following query:
$resclients=$mysqli->query("SELECT id,client_name FROM clients WHERE id IN ($result[])");
And I am wondering, is it bad practice to execute the above query in a for or foreach-loop, does it hurt the MySQL server?
Or, is it better to do LEFT JOINS or INNER JOINS or RIGHT JOINS?
Forgot to add, the $result[] is actually a two dimensional array.
Show your array:
Array
(
[0] => Array
(
[id] => 7
[resclients] => 6,7,8,9,10,11,12,13,14,15
)
[1] => Array
(
[id] => 5
[resclients] => 5
)
[2] => Array
(
[id] => 4
[resclients] => 4
)
)
Just a small portion of it.
You can use it as:
// a testing multidimensional array
$testArr = array(
array(
'one'=>1,
'two'=>2,
'three'=>3)
);
$yourIds = array();
foreach ($testArr as $value) {
foreach ($value as $finalVal) {
$yourIds[] = $finalVal[];
}
}
$implodedIds = implode(",",$yourIds);
echo "SELECT id,client_name FROM clients WHERE id IN ($implodedIds)";
Result:
SELECT id,client_name FROM clients WHERE id IN (1,2,3)
Note that: this is basic idea how can you use without using query in a loop.

Query 2 dimensional array using native php array functions

I have converted a CSV to a two dimensional array where the following array structure stores the column and row data
$table['status'] = ['active', 'active', 'inactive'];
$table['plan'] = ['annual', 'weekly', 'weekly '];
$table['spend'] = ['12,000', '19,000', '0' ];
print_r($table);
would appear as follows:
( [status] => Array ( [0] => active [1] => active [2] => inactive )
[plan] => Array ( [0] => annual [1] => weekly [2] => weekly )
[spend] => Array ( [0] => 12,000 [1] => 19,000 [2] => 0 ) )
I want to use native PHP array functions to query the arrays without having to write loops with nested conditions. If this was a MySQL database and I wanted to find the sum of spend from accounts with active status and weekly plans I would simply run the following query
SELECT SUM('Spend') FROM table WHERE status = 'Active' AND plan = 'Weekly';
But instead I have to take the following approach using a for loop
for ($index = 1; $index < count($table); $index++){
if (($table['status'][$index] == 'active') && ($table['plan'][$index] == 'weekly')){
$spend[$index] = $table['spend'][$index];
}
}
echo array_sum($spend);
This approach gives me a headache. Is there an obvious solution for refactoring this into php's native array functions or is a mess of explicit loops inevitable?
There aren't any native functions to do what you want. What's wrong with storing the information from the CSV files into a database?
If that's simply not an option then try foreach loops, they're much cleaner.
$spend = array();
foreach ($table['spend'] as $key => $amount)
{
if ($table['status'][$key] == 'active' && $table['plan'][$key] == 'weekly')
{
$spend[] = $amount;
}
}
Whilst it doesn't solve the loops issue it does help clean them up so you don't lose your mind so much.
Using Array Keys to get all "active" keys, then loop through only those to find the matches.
$keys = array_keys($table['status'], 'active');
foreach($keys as $key)
{
if($table['plan'][$key] == 'weekly')
{
$spend[] = $table['spend'][$key];
}
}
print_r($spend);
Spend:
Array
(
[0] => 19,000
)
this is pretty messy but I found one way of doing it
$keys = array_intersect(array_keys($table['status'], 'active'), array_keys($table['plan'], 'weekly'));
$subs['total'] = array_intersect_key($table['spend'], array_flip($keys));
print_r(array_sum($subs['total']));

how read multiple date values in PHP array and then subtract them, returning an int value

I have a task that I need to implement, in a nutshell I want to be able to read multiple date values from a table in mySQL using PHP then manipulate these values to get date difference in days, save these new days (int values) into another array for further manipulation (linear regression). My problem is I cant get to the point where I can save initial values retrieved from the DB into an array, but when I try to manipulate these values and save them into a second array, it does not work. here is my simple code:
$result = mysql_query("SELECT TO_DAYS(date) FROM ordering WHERE id=1",$conn);
$num_rows = mysql_num_rows($result);
// mysql_query($result,$conn) or die(mysql_error();
//echo $num_rows;
$data = array();
$days=array();
while (($row = mysql_fetch_array($result, MYSQL_ASSOC)) !== false){
$data[] = $row; // add the row in to the results (data) array
}
print_r($data); // print result
//This part is not working
for ($x=$num_rows;$x>0;$x--){
$days[x]=(($data[$x])-($data[$x-1]));
}
print_r($days);
mysql_close($conn);
If I don't include the for loop in my code, I get an output on the screen as follows:
Array (
[0] => Array ( [TO_DAYS(date)] => 735599 )
[1] => Array ( [TO_DAYS(date)] => 735630 )
[2] => Array ( [TO_DAYS(date)] => 735658 )
[3] => Array ( [TO_DAYS(date)] => 735689 )
[4] => Array ( [TO_DAYS(date)] => 735735 )
[5] => Array ( [TO_DAYS(date)] => 735780 )
[6] => Array ( [TO_DAYS(date)] => 735811 )
)
Please I really need some help here.
Thank You - Hamood
Try this:
for ($x = $num_rows - 1; $x > 0; $x--) {
$days[$x] = $data[$x]['TO_DAYS(date)'] - $data[$x-1]['TO_DAYS(date)'];
}
Here, $data[$x] is an array itself with key TO_DAYS(date), so you need to get your desired value with $data[$x]['TO_DAYS(date)'].

PHP extract array values with the same key into another array

I have an array as so:
$diff_date_results =
Array (
[0] => Array ( [differential] => 7.7 [date] => 2012-12-30 )
[1] => Array ( [differential] => 8.2 [date] => 2012-12-31 )
[2] => Array ( [differential] => 9.9 [date] => 2013-01-03 )
)
I would like to extract all values from the differential key of each of the inner arrays to use the array_sum function on the newly created array.
I have this, which draws out the three numbers for me, but I get php errors for each number as an undefined index. (Notice: Undefined index: 7.7 in C:\wamp\www\jquery\test.php on line 55)
My code thus far is as follows:
$diff_results = array();
foreach($diff_date_results as $entry){
$diff_results[$entry['differential']];
}
print_r($diff_results);
I am sure it is simple, I have been screwing around with it for way too long now, any help would be wonderful!
Thanks.
$diff_results = array();
foreach($diff_date_results as $entry){
$diff_results[] = $entry['differential'];
}
//just for displaying all differential
print_r($diff_results);
Now, you can use array_sum on $diff_results.
Moreover, if you want to have sum then you can use below method too.
$diff_results = "";
foreach($diff_date_results as $entry){
$diff_results = $diff_results + $entry['differential'];
}
//$diff_results will have sum of all differential
echo $diff_results;
$diff_results = array_map($diff_date_results,
function($entry) { return $entry['differential']; });
Do it like this:
$diff_results = array();
foreach($diff_date_results as $key => $entry){
$diff_results[] .= $entry['differential']];
}
print_r($diff_results);
Thanks.
$diff_date_results = array (
0 => array ( 'differential'=> 7.7, 'date' => 20),
1 => Array ( 'differential' => 8.8, 'date' => 20 ),
2 => Array ( 'differential' => 9.8 ,'date' => 20 ),
);
$value_differential=array();
foreach( $diff_date_results as $key=>$value){
print_r($value);
$value_differential[]=$value['differential'];
}
print_r(array_sum($value_differential));
For anyone stumbling across this question as I have, the best solution in my opinion is a working version of Barmars as below:
$diff_results = array_map(function($entry)
{
return $entry['differential'];
},
$diff_date_results);
it's a more elegant, 1 line solution (which I've expand to 5 lines for readability).

Categories