Calculate price with mysql query - mysql

gurus! I am stuck. Catalog items have prices dependent to its quantity. Here example of tables:
items: just item definitions
-------------------------
item_id | item_title
-------------------------
1 | "sample item"
2 | "another item"
items_prices: prices dependent to item quantity.
Less price taken for more quantity of item
----------------------------
item_id | quantity | price
----------------------------
1 | 1 | 100
1 | 5 | 80
1 | 10 | 60
2 | 1 | 120
2 | 3 | 100
cart
-------------------
item_id | quantity
-------------------
1 | 20
2 | 2
Is it possible to get current cart cost with single query?

select sum(x.totalcost)
from (
select c.item_id, c.quantity * ip.price as totalcost
from cart c
join items_prices ip
on c.item_id = ip.item_id
left join items_prices ip2
on ip2.quantity > ip.quantity
and c.quantity >= ip2.quantity
where c.quantity >= ip.quantity
and ip2.quantity is null
) x
The join back onto items_price again lets us filter out any cases where there is a greater quantity which still meets our criteria. This should be getting close to what we're after

Related

Get cheapset prices in price table

I have a price table. I want to list the cheapest price of the products with the same IDs in my table. How can I do it?
Table Name : prices
userID| productsID | price | stock | maks
-------------------------------------------
1 | C120221 | 100 | 3 | 1
2 | C120221 | 200 | 5 | 5
3 | BR120221 | 500 | 7 | 3
4 | BR120221 | 600 | 9 | 0
5 | BR120221 | 700 | 11 | 2
SQL
SELECT
MIN(price ) AS price ,
GROUP_CONCAT(userID) AS userID
FROM prices
WHERE price > 0
GROUP BY productsID
ORDER BY price ASC
In this case I want to list all the info of the user with the cheapest price. In the current query, I can get the data in the productsID and price fields, but I cannot get the data in the userID, stock and max fields of the user with these data. Where is the problem?
You are probably trying to find the line or lines that contain the lowest price.
SELECT
prices.*
FROM
(
SELECT
MIN(price) AS price,
productsID
FROM
prices
WHERE
price > 0
GROUP BY
productsID
) AS t1
JOIN prices ON prices.price = t1.price
AND prices.productsID = t1.productsID

How to count item from joined table?

I have 2 tables. sales and payment.
sales table (has around 900.000 records)
item_id | sale_id
------------------
1 | 1
2 | 1
3 | 1
1 | 2
1 | 3
3 | 3
payment table (also has around 900.000 records)
sale_id | payment_method
------------------------
1 | CASH
2 | CREDIT
3 | CASH
I'd like to know top 5 best seller items grouped by payment method. Something like this
item_id | total_sales | payment_method
--------------------------------------
1 | 2 | CASH
3 | 2 | CASH
So far I have
SELECT
a.item_id as item_id,
COUNT(a.item_id) as total_sales,
b.payment_method as payment_method
FROM sales a
LEFT JOIN payment b ON a.sale_id = b.sale_id
GROUP BY a.item_id
ORDER BY COUNT(a.item_id) DESC
However, the result is not correct.
How to get something like this?

How to retrieve two SUM() value from two tables based on foreign key and subtract them

I have 3 tables
products table purchase table sale table
+----+---------+ +----+-----------+-------+ +----+------------+--------+
| id | product | | id | product_id| pieces| | id | product_id | pieces |
+----+---------+ +----+-----------+-------+ +----+------------+--------+
| 1 | Tyre | | 1 | 3 | 5 | | 1 | 2 | 3 |
+----+---------+ +----+-----------+-------+ +----+------------+--------+
| 2 | Switch | | 2 | 1 | 3 | | 2 | 1 | 2 |
+----+---------+ +----+-----------+-------+ +----+------------+--------+
| 3 | Ring | | 3 | 2 | 6 | | 3 | 3 | 3 |
+----+---------+ +----+-----------+-------+ +----+------------+--------+ | 4 | Wheel | | 4 | 3 | 4 | | 4 | 2 | 1 |
+----+---------+ +----+-----------+-------+ +----+------------+--------+
I want to SUM() both pieces column in purchase table and sale table based on/GROUP BY product_id. Ex- SELECT products, SUM(pieces) FROM purchase GROUP BY product_id Same query for sale table.
I want to subtract the SUM() result to find out the remaining pieces. Ex- SUM(purchase.pieces) - SUM(sale.pieces) AS balance
And finally I need product name from products table, total pieces of same product in purchase table that means how many times a product has been sold such as Tyre - 5 pieces, same for sale table, and remaining pieces after subtract total sale of a product from total purchase of a product.
How can I do this using PHP and PDO?
you can use SUM() for the pieces column and have the difference to get the balance
SELECT p.id,
p.product,
IFNULL(total_purchase,0) total_purchase,
IFNULL(total_sales,0) total_sales,
IFNULL(total_purchase,0) - IFNULL(total_sales,0) balance
FROM (SELECT pd.id,
pd.product,
SUM(pc.pieces) total_purchase
FROM products pd
LEFT JOIN purchase pc
ON pd.id = pc.product_id
GROUP BY pd.id, pd.product
) p
JOIN (SELECT pd.id,
pd.product,
SUM(sl.pieces) total_sales
FROM products pd
LEFT JOIN sales sl
ON pd.id = sl.product_id
GROUP BY pd.id, pd.product
) s
ON p.id = s.id
ORDER BY p.id
Result
id product total_purchase total_sales balance
1 Tyre 3 2 1
2 Switch 6 4 2
3 Ring 9 3 6
4 Wheel 0 0 0
Something like this should be a good start:
select
products.product
purchases.Total as PurchasedPieces,
sales.Total as SoldPieces
purchases.Total - sales.Total as balance
from
products
left join (select(product_id,SUM(pieces) as Total from purchases group by product_id)) purchases on products.id = purchases.product_id
left join (select(product_id,SUM(pieces) as Total from sales group by product_id)) sales on products.id = sales.product_id

Mysql subtract from another table

I have tried to search this forum for an answer but can't seem to find one.
My problem: I have 3 tables. One with items, one with in-going deliveries and one with outgoing deliveries.
Table called items:
id | item_name
----------------
1 | Bike
2 | Helmet
3 | Pedal
4 | Light
Table called ingoing:
id | item_id | quantity
-----------------------
1 | 2 | 5
2 | 3 | 2
3 | 4 | 1
4 | 1 | 5
5 | 2 | 4
6 | 1 | 6
7 | 3 | 5
Table called outgoing:
id | item_id | quantity
-----------------------
1 | 3 | 2
2 | 1 | 1
3 | 2 | 3
4 | 3 | 4
5 | 1 | 2
6 | 2 | 1
7 | 4 | 1
What I want to do is get the total amount in stock by subtracting the outgoing deliveries from the in-going and order it by the item with the least amount.
Maybe there is a better way to do this?
This is the query that I got, but the SUM amounts isn't correct. Can someone help me and explain why the SUM amounts isn't correct and how should I solve this with the best way?
SELECT items.id AS ID,
items.item_name,
Sum(ingoing.quantity) - Sum(outgoing.quantity) AS InStock
FROM items
LEFT JOIN ingoing
ON ingoing.item_id = items.id
LEFT JOIN outgoing
ON outgoing.item_id = items.id
GROUP BY ID
ORDER BY InStock ASC
This is the result I want from this:
ID | item_name | InStock
---------------------------
4 | Light | 0
3 | Pedal | 1
2 | Helmet | 5
1 | Bike | 8
What I Get:
ID | item_name | InStock
---------------------------
4 | Light | 0
3 | Pedal | 2
2 | Helmet | 10
1 | Bike | 16
It can be easy to forget the multiplicative effect of a join. When you encounter problems like this, check the result of the join, prior to filtering/grouping:
SELECT items.id,
items.item_name,
ingoing.id AS ingoing,
outgoing.id AS outgoing
FROM items
LEFT JOIN ingoing
ON ingoing.item_id = items.id
LEFT JOIN outgoing
ON outgoing.item_id = items.id
See it on sqlfiddle.
As you can see, the resultset contains multiple records with the same ingoing.id values, and multiple records with the same outgoing.id values. This is because each ingoing record for a particular item has joined with every outgoing record for that same item: thus there are 4 pedals in the resultset (2 incoming x 2 outgoing), etc.
Aggregating each table by item prior to joining (and thus ensuring that there is only 1 record per item on each side of the join) will achieve what you're after:
SELECT items.id AS ID,
items.item_name,
ingoing.quantity - outgoing.quantity AS InStock
FROM items
LEFT JOIN (
SELECT item_id AS id, SUM(quantity) AS quantity
FROM ingoing
GROUP BY item_id
) AS ingoing USING (id)
LEFT JOIN (
SELECT item_id AS id, SUM(quantity) AS quantity
FROM outgoing
GROUP BY item_id
) AS outgoing USING (id)
ORDER BY InStock ASC
See it on sqlfiddle.
Note that your problem would have been greatly simplified by only having a single underlying table of stock movements, with positive quantities indicating movements in one direction and negative quantities indicating movements in the opposite direction: then a simple groupwise summation of the whole table would yield your desired results.
Try this query:
SELECT items.id AS ID, items.item_name, (SELECT SUM(quantity) from ingoing
WHERE ingoing.item_id = items.id) - (SELECT SUM(quantity) from outgoing WHERE
outgoing.item_id = items.id) AS InStock FROM items ORDER BY InStock ASC;

MySQL subtract from isolated subquery

I have a table containing inventory
ID | Product ID | In_Transit | Quantity | Cumulative Quantity
=====+================+==============+==============+====================
1 | 1 | 0 | 1000 | 1000
2 | 1 | 0 | 1 | 1001
3 | 1 | 1 | 54 | 1055
4 | 1 | 1 | 1 | 1056
So the total inventory for product id 1 is '1056' I get this using a SELECT MAX(ID) subquery join with the table to get its cumulative quantity which is 1056.
I would like to get the Inventory total (subtracting all the amounts in transit)
So 1056 - 54 - 1 = 1001
How would I get this in one query so i get
Product ID | Total Inventory | Inventory on Hand (Excluding in Transit |
===========+=================+=========================================
1 | 1056 | 1001
Also i need to use the cumulative inventory to get the total as opposed to 'SUM', except for summing those in transit because (those not in transit) have a large number of records and they take ages to SUM. I can use it to sum those in transit because there are far fewer records
SELECT
a.product_id
, a.cumulative as total_inventory
, a.cumulative - COALESCE(b.quantity,0) AS inventory_on_hand
FROM table1 a
JOIN
( SELECT MAX(id) AS max_id
FROM table1
GROUP BY product_id
) m ON (m.max_id = a.id)
LEFT JOIN
( SELECT product_id, SUM(quantity)
FROM table1
WHERE in_transit = 1
GROUP BY product_id
) b ON (a.product_id = b.product_id)