I have a query that returns a list of rows from mysql database, the list of rows generated have of rows values being the same.
Table
id mAmount paidAmount
1 100 50
1 100 30
2 200 20
2 200 150
I actually want to sum the paidAmount and subtract from just one of mAmount value per the same id.
For instance
1 | (100) - (50 + 0) = 50 |
1 | (100) - (30 + 50) = 20 |
2 | (200) - (20 + 0) = 180 |
2 | (200) - (150 + 20) = 30 |
I do not want anyone any to give me the entire codes to this, but an idea as to how to go about it using either php with while loop or possibly foreach statements. Thanks really appreciate.
Just have to loop and accumulate the paid amount, then do the subtraction.
For this example I suppose you pre-order your records by id and pass the records to an multidimensional array called rows:
$currentId = $rows[0]['id'];
$accumulated = 0;
foreach ( $rows as $row ) {
if ( $row['id'] != $currentId ) {
$accumulated = 0;
$currentId = $row['id'];
} // end if not current id
$accumulated += $row['paidAmount'];
$balance = $row['mAmount'] - $accumulated;
$row['balance'] = $balance;
$result[] = $row;
} // end foreach
print_r ( $result );
Results are printed like this:
Array
(
[0] => Array
(
[id] => 1
[mAmount] => 100
[paidAmount] => 50
[balance] => 50
)
[1] => Array
(
[id] => 1
[mAmount] => 100
[paidAmount] => 30
[balance] => 20
)
[2] => Array
(
[id] => 2
[mAmount] => 200
[paidAmount] => 20
[balance] => 180
)
[3] => Array
(
[id] => 2
[mAmount] => 200
[paidAmount] => 150
[balance] => 30
)
)
Related
I'm trying to restructure my arrays so that I can get the desired output in one final array that will be used to fill a csv, eventually spreadsheet.
My first msyql query and the resulting array give me this structure:
array(
[0] => Array
(
[sku_id] => 1
[dealer_id] => 1976
[locations] => 1
[groupID] => 1
[frame] => 1051
[cover] => 1150
[color] => 99
[start_date] => 2018-03-
)
[1] => Array
(
[sku_id] => 1
[dealer_id] => 5400
[locations] => 1
[groupID] => 1
[frame] => 1051
[cover] => 1150
[color] => 99
[start_date] => 2017-04-
)
[2] => Array
(
[sku_id] => 1
[dealer_id] => 11316
[locations] => 1
[groupID] => 1
[frame] => 1051
[cover] => 1150
[color] => 99
[start_date] => 2017-02-
)
)
So I get 3 records, each for the same product (sku_id) but a different customer(dealer_id). Then I match this data up in a similar table in DB2 to get quantity for each order of the sku_id. That 2nd query/array shows this:
Array
(
[0] => Array
(
[CSTNOC] => 1976
[TOTALQTY] => 2
)
[1] => Array
(
[CSTNOC] => 5400
[TOTALQTY] => 5
)
[2] => Array
(
[CSTNOC] => 11316
[TOTALQTY] => 14
)
)
However, this is what I'm trying to achieve.
In the below example, sku_id, groupID and location would come directly from the first query. Days is the number of days between start_date (from query 1) and curDate(). Qty is orqtyc from query 2 and Average is a calculation based on locations, days and qty. Each row is based on a different customer, so even though the below example is for one sku, the rows signify a different customer with different locations, qty, etc.
SKU_id | groupID | locations (n) | Days (x) | Qty(q) | Average (x/(q/n))
--------------------------------------------------------------------------------
123 1 3 120 15 24
123 1 2 12 6 4
The Report or CSV would then only show one line item for the above:
SKU | Group | Average Days | Total units sold
123 | 1 | 28 | 21
Basically, for every sku I'm getting those records and then I need to do those calculations by row, and get a total of those values for each sku. The report will only have one line item per sku.
I have everything I need to get there, but how can I structure a final array to get my desired outputs like above?
FULL SCRIPT:
$skuQuery = "
SELECT
sku_id,
dealer_id,
locations,
s.sku_group_id as groupID,
s.frame as frame,
s.cover1 as cover,
s.color1 as color,
start_date - interval 7 day as start_date
from products p
inner join skus s on p.sku_id = s.id
where curdate() between p.start_date and p.expire_date
group by sku_id, dealer_id
limit 3";
$skuRslt = mysqli_query($conn,$skuQuery);
while($skuRow = mysqli_fetch_assoc($skuRslt)){
$skuResult[] = $skuRow;
$dealerQuery = "
SELECT
cstnoc,
sum(orqtyc) as TotalQTY
from table
where cstnoc = {$skuRow['dealer_id']}
AND framec = {$skuRow['frame']}
AND colr1c = {$skuRow['color']}
AND covr1c = {$skuRow['cover']}
AND extd2d >= " . str_replace('-', '', $skuRow['start_date']) . "
group by cstnoc, framec
";
$dealerRslt = odbc_exec($DB2Conn, $dealerQuery);
foreach($skuResult as $skuRow){
while($dealerRow = odbc_fetch_array($dealerRslt)){
$dealerResult[] = $dealerRow;
}
}
print_r($dealerResult);
}
I'm trying to build arrays based off of two queries, one in mysql one on db2. I've built the main arrays, the first dealing with product info and the 2nd dealing with customer info but they have some values in common.
This is working as far as structure but I've been trying to build a final array to contain data from the initial arrays that will build a report.
For now, I'm just going to try and output a report or csv file for each sku_id from the first query, and the total number/ quantity from the 2nd query.
The 2nd query/array contain multiple attributes on a per product/customer basis.
(
[1] => 2
)
Array
(
[1] => 5
)
Array
(
[1] => 14
)
Basically, I pulled three records from the first table for sku_id '1' and matched those three records in db2 for the same sku. Each element corresponds to a customer, so this structure says "customer A had 2 of sku_id 1, customer B had 5 of sku_id 1 and customer C had 14 of sku_id 1'
For the purpose of the report, each line will be for each sku so I want to instead output this as:
array
(
[1] => 21
)
Showing that overall, sku_id 1 had a total of 21. So I still want to keep my initial arrays structured like they are, but I want to modify my final array to just give me line items for the report.
How can I do that?
$skuQuery = "
SELECT
sku_id,
dealer_id,
locations,
s.sku_group_id as groupID,
s.frame as frame,
s.cover1 as cover,
s.color1 as color,
start_date - interval 7 day as start_date
from products p
inner join skus s on p.sku_id = s.id
where curdate() between p.start_date and p.expire_date
group by sku_id, dealer_id
limit 3";
$skuRslt = mysqli_query($conn,$skuQuery);
while($skuRow = mysqli_fetch_assoc($skuRslt)){
$skuResult['sku_id'] = $skuRow;
$dealerQuery = "
SELECT
cstnoc,
sum(orqtyc) as TotalQTY
from table
where cstnoc = {$skuRow['dealer_id']}
AND framec = {$skuRow['frame']}
AND colr1c = {$skuRow['color']}
AND covr1c = {$skuRow['cover']}
AND extd2d >= " . str_replace('-', '', $skuRow['start_date']) . "
group by cstnoc, framec
";
$dealerRslt = odbc_exec($DB2Conn, $dealerQuery);
$dealerResult = [];
foreach($skuResult as $skuRow){
while($dealerRow = odbc_fetch_array($dealerRslt)){
if ( !isset($dealerResult[$dealerRow['CSTNOC']]) ) {
$dealerResult[$dealerRow['CSTNOC']] = 0;
}
$dealerResult[$dealerRow['CSTNOC']] += $dealerRow['TOTALQTY'];
}
}
$skuTots = array_fill_keys(array_unique(array_column($skuResult, 'sku_id')), 0);
foreach ($skuResult as $rec) {
$skuTots[$rec['sku_id']] += $dealerResult[$rec['dealer_id']];
}
print_r($skuTots);
}
UPDATE:
This is the print out for my first two arrays:
Array
(
[0] => Array
(
[sku_id] => 1
[dealer_id] => 1976
[locations] => 1
[groupID] => 1
[frame] => 1051
[cover] => 1150
[color] => 99
[start_date] => 2018-03-
)
[1] => Array
(
[sku_id] => 1
[dealer_id] => 5400
[locations] => 1
[groupID] => 1
[frame] => 1051
[cover] => 1150
[color] => 99
[start_date] => 2017-04-
)
[2] => Array
(
[sku_id] => 1
[dealer_id] => 11316
[locations] => 1
[groupID] => 1
[frame] => 1051
[cover] => 1150
[color] => 99
[start_date] => 2017-02-
)
)
Array
(
[0] => Array
(
[CSTNOC] => 1976
[TOTALQTY] => 2
)
[1] => Array
(
[CSTNOC] => 5400
[TOTALQTY] => 5
)
[2] => Array
(
[CSTNOC] => 11316
[TOTALQTY] => 14
)
)
And here is an example of my end result I'm trying to achieve:
In the below example, sku_id, groupID and location would come directly from the first query. Days is the number of days between start_date (from query 1) and curDate(). Qty is orqtyc from query 2 and Average is a calculation based on locations, days and qty. Each row is based on a different customer, so even though the below example is for one sku, the rows signify a different customer with different locations, qty, etc.
SKU_id | groupID | locations (n) | Days (x) | Qty(q) | Average (x/(q/n))
--------------------------------------------------------------------------------
123 1 3 120 15 24
123 1 2 12 6 4
The Report or CSV would then only show one line item for the above:
SKU | Group | Average Days | Total units sold
123 | 1 | 28 | 21
Basically, for every sku I'm getting those records and then I need to do those calculations by row, and get a total of those values for each sku. The report will only have one line item per sku.
Im trying to figure something out. I want to apply coupon/discount amount to multiple products evenly.
For example if I have an array with 3 items
Array
(
[0] => stdClass Object
(
[id] => 1
[price] => 10.00
)
[1] => stdClass Object
(
[id] => 2
[price] => 20.00
)
[2] => stdClass Object
(
[id] => 3
[price] => 30.00
)
)
my coupon vale is 10 $ off
and I have tried this:
foreach ($array as $row) {
$data['price'] = ($row->price - 10 / 3) * 100
}
So basically I want to deduct from each item price proportionally total of 10 and end up with something like:
Array
(
[0] => stdClass Object
(
[id] => 1
[price] => 7.50
)
[1] => stdClass Object
(
[id] => 2
[price] => 17.50
)
[2] => stdClass Object
(
[id] => 3
[price] => 25.00
)
)
where total price sum is 50 instead original of 60
So, from the comments under the question, you want to distribute the coupon value proportionally (not evenly) to prices of all items. That's pretty easy, it's more a mathematical problem than a programming one.
Calculate x as coupon / sum(prices)
Iterate through all items and subtract x * item_price from item_price
That's it.
For your example (coupon = 10, prices = [10, 20, 30]), the result is:
x = 10 / 60 = 0.1666667
Subtract x * item_price from each item's item_price:
10 - 10 * 0.1666667 = 10 - 1.6666667 = 8.33333
20 - 20 * 0.1666667 = 20 - 3.3333333 = 16.6666
30 - 30 * 0.1666667 = 30 - 5 = 25
To verify: 1.666667 + 3.3333333 + 5 = 10
Given an array and I need to to display the average after every seventh row
Array
(
[0] => Array
(
[date] => 01-03-2015
[site_id] => 1
[starting_reading] => 567
[close_reading] => 567
)
[1] => Array
(
[date] => 03-03-2015
[site_id] => 1
[starting_reading] => 567
[close_reading] => 567
)
[2] => Array
(
[date] => 08-03-2015
[site_id] => 1
[starting_reading] => 567
[close_reading] => 567
)
)
Now what i need, is to display all avg reading in 7 days like:
1 to 7
--------------------- avg=close-start----------
8 to 14
--------------------- avg=close-start----------
15 to 21
--------------------- avg=close-start----------
22 to 28
--------------------- avg=close-start----------
29 to 31
--------------------- avg=close-start----------
date starting_reading close_reading
01-03-2015
03-03-2015
--------------------- avg=close-start----------
08-03-2015
--------------------- avg=close-start----------
//$arr is as the array you described
foreach($arr as $k => $v){
//$k will be some integer 0...count($arr)-1 assuming a 'normal' index
//$v is your child array, where you can access attributes such as $v['date']
//every seventh row can be done in a number of ways, the easiest way is:
if($k % 7 == 0){
//then show new line. This will happen every time the number divides into seven. 0, 7, 14, 21... etc.
var_dump($v); will output your child of the seventh (multiple) item
}
}
Including your example for dates and averages assuming array is correctly formatted
//$arr is as the array you described
$close = 0;
$start = 0;
foreach($arr as $k => $v){
//$k will be some integer 0...count($arr)-1 assuming a 'normal' index
//$v is your child array, where you can access attributes such as $v['date']
//every seventh row can be done in a number of ways, the easiest way is:
if($k % 7 == 0){
$close = 0; //reset close
$start = 0; //reset start
}
$close += (int)$v['close_reading'];
$start += (int)$v['starting_reading'];
if(($k + 1) % 7 == 0){ //this is the last row, 6, 13, 20 etc.
echo ($k-5).' to '.($k+1);
echo 'Average: '.(($close - $start) / 7);
}
}
i have a
Book ID Array
Array
(
[0] => 61
[1] => 72
[2] => 78
[3] => 100
[4] => 102
)
now from another table table_bookPrice where price filed is given
i want that select all price from table_bookPrice where book id is in given array (book ID Array) and if price is not mentioned in table_bookPrice field then it would be automatic 500
what will be exact query
so the array i got is like this
Book Price Array
Array
(
[0] => 150
[1] => 100
[2] => 500 ( not mentioned in table, so it is 500)
[3] => 300
[4] => 200
)
I am at work so could not test or compile it, but I hope my logic is understandable.
Not sure if this will work but something along these lines
$book_price_array = array(); //contents to be added.
// loop through the array an examine its price by querying your table.
foreach ($book_id_array as $key => $value) {
$price = mysql_query("SELECT price FROM table_bookPrice
WHERE book_id = {$value}");
// there is a price, set the price.
if ($price > 0 && $price != NULL) $book_price_array[$key] = $price;
// there is no price, set the default price
else $book_price_array[$key] = 500;
}
Here's the test database I built for your problem:
mysql> select * from table_bookPrice;
+----+-------+--------+
| id | price | bookid |
+----+-------+--------+
| 1 | 150 | 61 |
| 2 | 100 | 72 |
| 3 | 300 | 100 |
| 4 | 200 | 102 |
+----+-------+--------+
4 rows in set (0.00 sec)
Here's the PHP code:
<?php
$books=array(61,72,78,100,102);
// establish an assoc array of bookid => default_price
$prices=array();
foreach($books as $bookid){
$prices["$bookid"]=500;
}
// build query to select all prices stored in database
$bookids=implode(', ',$books);
mysql_connect('localhost','aj','nothing') or die('unable to connect!');
mysql_select_db('books') or die('unable to select db!');
$stmt="SELECT bp.bookid, bp.price FROM table_bookPrice bp WHERE bp.bookid IN ($bookids)";
$res=mysql_query($stmt);
while( ($rec= mysql_fetch_assoc($res)) ){
$idstr=(string)$rec['bookid'];
$prices[$idstr]=$rec['price'];
}
print_r($prices);
?>
This outputs:
Array
(
[61] => 150
[72] => 100
[78] => 500
[100] => 300
[102] => 200
)