I have a weight calculated, and a database table that contains the range of amounts, now I want to check if the calculated weight is between the ranges in my table.
Shipping Fee Table
--------------------------------------------------
id | weight_from | weight_to | amount |
----+---------------+--------------+--------------
1 | 0.5 | 100 | 100 |
2 | 500 | 1000 | 120 |
3 | 1000 | 3000 | 180 |
For example the calculated weight is 505kg it will find it on the table if it's between weight_from & weight_to
I found something like this, but it is not like what I'm trying to do, because it pass a number, and not getting the value of database table.
Code
$fee = Fee::whereBetween('column', [1, 150])->first();
you can use > and < with two where condition
$fee = Fee::where('weight_from', '>=', 500)->where('weight_to', '<=', 500)->first();
Related
I have two three tables:
// invoices
+----+----------------+
| id | invoice_code |
+----+----------------+
| 1 | d09823r230r4 |
| 2 | 34tf354f45tf |
+----+----------------+
// commodities
+----+-------------+------------+--------+
| id | invoice_id | product_id | number |
+----+-------------+------------+--------+
| 1 | 1 | 1 | 2 |
| 2 | 1 | 3 | 4 |
+----+-------------+------------+--------+
-- number columns is the number of each ordered product in the invoice
// products
// invoices
+----+-----------+---------+
| id | name | price |
+----+-----------+---------+
| 1 | SFX-300 | 15000 |
| 2 | GB32-b10 | 2000 |
| 3 | SVX-m30 | 1200 |
+----+-----------+---------+
All I need to do is calculating the total price of an invoice. Here is the formula to calculate the total price for invoice x:
$total_invoice_price = 0;
foreach( $invoice_x->commodities as $commodity){
$total_invoice_price += ( $commodity.number * <products.price> )
}
echo $total_invoice_price;
The problem is about getting <products.price>. It needs one more join to products table. Any idea how can I do that using Laravel relationships ?
If you just need the total price, this could be done in pure sql with aggregate statements and joins over the three tables.
SELECT invoice.invoice_code, SUM(product.price * commodities.number)
FROM invoice
JOIN commodities ON invoice.id = commodities.invoice_id
JOIN product ON product.id = commodities.product_id
GROUP BY invoice.id
To save the query, you should do eager loading using "with()" the model you wish to join.
I'm not sure how you named your model and how well it linked to each other.
Let's assume that it've been done in the conventional way.
Here is the script.
$total_invoice_price = $invoice_x->commodities
->with('products')
->get()
->map(function ($commodity) {
return $commodity->number * $commodity->product->price;
})
->sum();
What I've done is after getting the products joined with each commodity. I do the get() to have the commodities collection. The from the collection, we do map on each commodity and return the number and price of product. Then we multiply and return as the sum of each commodity record. After that we sum all the totals to the grand total and get your result.
I wrote the code without testing, so try to adjust it to your code.
Please check below Query
$invoices_total = DB::table('invoices')
->join('products', 'invoices.id', '=', 'commodities.invoice_id')
->join('commodities', 'products.id', '=', 'commodities.product_id')
->sum('products.price * commodities.number')
->groupBy('invoices.id')
->get();
I have a stock table that has several items oderd by users and the item can be having different unit prices depending on the time they were ordered, so you can find an item has more than 5 entries with different prices like the below table:
+----+----------+----------+------------+-------------+-------+
| ID | unitCost | quantity | totalPrice | orderNumber | item |
+----+----------+----------+------------+-------------+-------+
| 1 | 20 | 5 | 100 | OD003 | Pen |
| 2 | 15 | 3 | 45 | OD004 | Pen |
| 3 | 22 | 10 | 220 | OD005 | Books |
| 4 | 13 | 7 | 91 | OD006 | Pen |
+----+----------+----------+------------+-------------+-------+
So am trying to get 10 pens from the table. And the logic should be like this
When I take the first and they are not enough from the first row, I will go to the next row and get the remaining quantity and if it will not be enough it will go to the next till I get the 10 pens that I needed.
Then the price of the 10 pens I get from the table will be the average of unit price of each pen i got.
Please help me solve this in mysql query.
I would get the result from mysql and put it inside array to loop it.
$total_order = 40; $price = 0;
foreach($result as $key => $value) {
if ($value['quantity'] < $total_order) {
$price += $value['quantity']*$value['unitCost'];
} else {
$price += $total_order*$value['unitCost'];
break; //exit loop and stop calculating
}
$total_order = $total_order-$value['quantity'];
}
You may need to tweak the code above a bit to meet your criteria. e.g: Pen price only.
EXPLAIN
Let's say we have this transaction table :
+----+-------------+--------+----------------+----------------+---------------------+
| id | id_customer | amount | id_where_trans | id_money_from | date_trans |
+----+-------------+--------+----------------+----------------+---------------------+
| 1 | 10 | 10 | 100 | NULL | 2015-07-20 10:20:30 |
| 2 | 10 | -2 | 100 | NULL | 2015-07-21 09:10:11 |
| 3 | 10 | 7 | 120 | NULL | 2015-07-24 18:22:25 |
| 4 | 10 | -11 | 120 | here the magic | 2015-07-24 18:22:26 |
+----+-------------+--------+----------------+----------------+---------------------+
Read this in "human" language:
id 1 => Customer Alessandro (id_customer 10) charge 10€ on his account in shop A (id_where trans = 100)
id 2 => Customer Alessandro spent 2€ on Shop A
id 3 => Customer Alessandro charge 7€ on his account in shop B
id 4 => Customer ALessandro spend 11€ in shop B.
At the end of period (month, for example), Shop B need to receive 8€ (+10-2) from another shop, in our example shop A.
/end of human read.
You imagine that insert is a simple (for id 4, for example):
INSERT INTO transaction (id_customer, amount, id_where_trans, date) VALUES (10,-11,120,2015-07-24 18:22:26)
GOAL
My goal is set - during the insert, and if possible / simpler via PHP - the SQL splitted in two or more SELECT:
INSERT INTO transaction (id_customer, amount, id_where_trans, id_money_from, date) VALUES (10,-8,120,100,2015-07-24 18:22:26)
INSERT INTO transaction (id_customer, amount, id_where_trans, id_money_from, date) VALUES (10,-3,120,NULL,2015-07-24 18:22:27)
+----+-------------+--------+----------------+------------+---------------------+
| id | id_customer | amount | id_where_trans | id_money_from | date |
+----+-------------+--------+----------------+------------+---------------------+
| 1 | 10 | 10 | 100 | NULL | 2015-07-20 10:20:30 |
| 2 | 10 | -2 | 100 | NULL | 2015-07-21 09:10:11 |
| 3 | 10 | 7 | 120 | NULL | 2015-07-24 18:22:25 |
| 4 | 10 | -8 | 120 | 100 | 2015-07-24 18:22:26 |
| 5 | 10 | -3 | 120 | NULL | 2015-07-24 18:22:27 |
+----+-------------+--------+----------------+------------+---------------------+
If I can get a table with that informations, I can run a query that make my final job correctly.
Basically, I need to calculate the id_shop where money are taken for discharge (in this case, -8 from 100, that made previous charge, and so is NOT NULL, and -3 from 120,itself, THIS IS NULL).
Please note that FIRST I consume / discharge the previous charge (id 4 now has id_money_from 100), AFTER I will consume / discharge others amounts (id 5 in effect is NULL, because that -3 has taken from id 3)
ASSUMPTION / MANDATARY
1) id are INCREMENTAL, no concurrency. Date are INCREMENTAL, date of id 4 is >= of id 3 and so on.
2) If amount of last recharge is made from same id where transaction is done (see id 1 and id 2) insert NULL (I need mandatary NULL)
3) First charge made, first need to be zero-ed, and so on.
MY LOGIC / PSEUDOCODE
1) If a transaction is negative, make a recursive getting LAST positive charge which, summed to the negative susequential, is not zero.
getted this charge, if id_where_trans==id_money_from we need insert, simply insert, with NULL
INSERT INTO transaction (id_customer, amount, id_where_trans, id_money_from, date) VALUES (10,-2,120,NULL,2015-07-24 18:22:26)
Recursive start here
If this amount is <= of last recharge, walking in database and split negative in two or more id_where_trans (problaby in real scenario this will be impossible, but I need to think that amount from discharge (id_money_from) could be splitted by 2, 3, x id_where_trans). For example, if SHOP A charge +1, Shop B charge +1, Shop C charge +1 and SHOP D DISCHARGE -3, we need to insert 3 different rows.
$amount_to_discharge = x;
$last_positive = $query->("SELECT * FROM transaction WHERE "); // make the SUB-SUM
if ($last_positive['amount'] >= $amount_to_discharge) {
$query->("INSERT INTO......");
} else {
// start recursive
$sql = "SELECT * FROM AMOUNT WHERE amount > 0 AND id < $last_positive['id']";
$new_search = $query->sql($sql);
// how implement correctly that recursive?
}
Thank you guy. Let me know if you need others explain!
Currently we store hours in a table that has a percentage field to distribute data across the week.
eg.
| dayint | daytext | hours | percent |
+--------+---------+-------+---------+
| 1 | mon | 9 | 0.14 |
| 2 | tue | 15 | 0.23 |
| 3 | wed | 9 | 0.14 |
| 4 | thu | 9 | 0.14 |
| 5 | fri | 0 | 0.00 |
| 6 | sat | 23 | 0.35 |
We are now adding a monthly distribution as well as weekly, so to calculate this I am:
Getting number of weeks in a month.
$weeks = $days_in_month/7
Iterating through each day's percent and dividing it by number of weeks.
$percent = $day['percent'] / $weeks
If my assumption is correct, this should distribute data across the month evenly. The problem is that it is consistently about 1ish % extra for the month.
If I enter 1000, I get 1013. If I enter 200, I get 202. Maybe I am just going about it wrong mathematically, any help is appreciated.
If your percent column stores data that has been rounded and is used in your monthly calculation as opposed to displaying rounded results that are stored accurately elsewhere then you will get rounding errors.
The example below shows the results for three weeks and the tables afterwards show the results using the actual data and the rounded data.
|Hours|Actual |Rounded| |Hours|Actual |Rounded| |Hours|Actual |Rounded|
| 9|0.13846153846154| 0.14| | 10|0.15625000| 0.16| | 8|0.135593220339| 0.14|
| 15|0.23076923076923| 0.23| | 14|0.21875000| 0.22| | 13|0.220338983051| 0.22|
| 9|0.13846153846154| 0.14| | 8|0.12500000| 0.13| | 11|0.186440677966| 0.19|
| 9|0.13846153846154| 0.14| | 10|0.15625000| 0.16| | 7|0.118644067797| 0.12|
| 0|0.00000000000000| 0| | 1|0.01562500| 0.02| | 2|0.033898305085| 0.03|
| 23|0.35384615384615| 0.35| | 21|0.32812500| 0.33| | 18|0.305084745763| 0.31|
| 65|1.00000000000000| 1.00| | 64|1.00000000| 1.02| | 59|1.000000000000| 1.01|
Over the three weeks iterating with
$percent = $day['percent'] / $weeks
actual column gives the results
0.14343
0.22329
0.14997
0.13779
0.01651
0.32902
1.00000
whereas rounded column gives
0.146666667
0.223333333
0.153333333
0.14
0.016666667
0.33
1.01
Remember rounded results always go up or stay the same never downwards, so the error will always be slightly more than you expect.
I decided to change my approach and go about it like this:
Get the total hours for the month by looping through:
$total = $total + $day['hours'];
Use the stored hours instead of the percent to calculate a new percent using:
$percent = $v['hours']/$total;
This approach returns the correct data.
I have the following table and want to know how to set up a column total to calculate the sum of the row. I want the total column to calculate first_bid - second_bid.
id | First Bid | Second Bid | Total
0 | 7 | 1 | (first_bid)-(second_bid)
1 | 8 | 2 |
2 | 5 | 3 |
3 | 4 | 4 |
4 | 5 | 5 |
5 | 5 | 6 |
I need to display to the user all previous bids and total on a page. The total should be in descending order also.
SELECT id, First_Bid, Second_Bid, First_Bid - Second_Bid AS Total
For the grand total, you'd have to run a second query with SUM() aggregate functions. Which is somewhat redundant, since you can just do the summation in your client as you retrieve the data. e.g.
$total = 0;
while($row = fetch_from_db($result)) {
$total += $result['Total'];
... display row data ...
}
... display total ...
You can just calculate the total when you are querying the database.
SELECT first_bid, second_bid, (first_bid - second_bid) as total FROM table ORDER BY 3 DESC
Something along these lines
Try this query:
SELECT *, (First Bid-Second Bid) as total from TABLE