Query using case and update the last record - mysql

I have two tables
oc_stock_hpp
id product_id stock
2 1234 0
3 5678 6
4 1234 2
6 1234 3
9 5678 7
oc_product
id product_id quantity
1 1234 7
23 5678 9
My purpose is to update the difference value (between SUM(stock) and quantity) in the stock field table oc_stock_hpp.
If the SUM(stock) > quantity then subtract the difference from the last record of stock
If the SUM(stock) > quantity then add the difference from the last record of stock
so the result will be like this
id product_id stock
2 1234 0
3 5678 6
4 1234 2
6 1234 5
9 5678 3
I have tried this but error
CASE
WHEN SUM(shpp1.stock) > p.quantity
THEN UPDATE oc_stock_hpp shpp1 INNER JOIN oc_product p ON shpp1.product_id = p.product_id
SET shpp1.stock = (shpp1.stock - ((SELECT SUM(shpp2.stock) FROM oc_stock_hpp shpp2 LEFT JOIN oc.product p WHERE shpp2.product_id = p.product_id) - p.quantity)
WHERE shpp1.id = (SELECT MAX(id) FROM (SELECT * FROM oc_stock_hpp) o1 WHERE product_id = p.product_id)
WHEN SUM(shpp1.stock) < p.quantity
THEN UPDATE oc_stock_hpp shpp1 INNER JOIN oc_product p ON shpp1.product_id = p.product_id
SET shpp1.stock = (shpp1.stock + (p.quantity - (SELECT SUM(shpp2.stock) FROM oc_stock_hpp shpp2 LEFT JOIN oc.product p WHERE shpp2.product_id = p.product_id))
WHERE shpp1.id = (SELECT MAX(id) FROM (SELECT * FROM oc_stock_hpp) o1 WHERE product_id = p.product_id)
END
FROM oc_product p
LEFT JOIN oc_stock_hpp shpp ON shpp.product_id = p.product_id

Join the 2 tables to a query that returns the last id and total stock for each product:
UPDATE oc_stock_hpp s
INNER JOIN oc_product p ON p.product_id = s.product_id
INNER JOIN (SELECT MAX(id) id, SUM(stock) stock FROM oc_stock_hpp GROUP BY product_id) t ON t.id = s.id
SET s.stock = s.stock + p.quantity - t.stock;
See the demo.

Related

Select count of total products as well as out of stock products from table

I have to 3 tables: product, product_to_store, store
product table
id quantity status
1 1 1
2 0 1
3 0 1
4 23 1
product_to_store table
store_id product_id
1 1
2 2
1 3
2 4
store table
id name
1 store1
2 store2
To find total products I can run query to fetch all products in table product where status of product is enabled.
select count(*) from product where status=1
total name
2 Store 1
2 store 2
To find total out of stock products I can run below query after joining all 3 tables and using group by store_id:
Select count(*) as outofproducts from product where quantity=0;
Result come like this:
outofproducts name
1 Store 1
1 store 2
But I want combination of above 2 results in single query like below:
outofproducts total name
1 2 Store 1
1 2 store 2
You'd use conditional aggregatiopn, i.e. sum/count over conditions:
select
s.name,
sum(p.quantity > 0) as in_stock,
sum(p.quantity = 0) as out_of_stock,
count(*) as total
from store s
join product_to_store ps on ps.store_id = s.id
join product p on p.id = ps.product_id
group by s.name
order by s.name;
This makes use of MySQL's true = 1, false = 0. If you don't like it, replace sum(p.quantity = 0) with sum(case when p.quantity = 0 then 1 else 0 end) or count(case when p.quantity = 0 then 1 end).
You can start query from store table so that we will get total rows as store table data.
Then use nested query for each store to get out of product and total product count
select
(Select count(*) as outofproducts from product_to_store ps inner join product p on p.id = ps.product_id where quantity=0 and ps.store_id = s.id ) as outofproducts ,
(Select count(*) as count from product_to_store ps inner join product p on p.id = ps.product_id where ps.store_id = s.id ) as totalCount,
s.name
from store s
You could join the related subquery for count
select t1.name, t1.outofproducts, t2.total
from(
select b.id, b.name , count(*) outofproducts
from product_to_store c
inner join product a on a.id = c.product_id
inner join store b on a.id = c.store_id
where a.quantity = 0
group by b.id, b.name
) t1
inner join (
select b.id, b.name , count(*) total
from product_to_store c
inner join product a on a.id = c.product_id
inner join store b on a.id = c.store_id
group by b.id, b.name
) t2 on t1.id = t2.id

How to subtract one table column values to the other table column values

I have two tables Stock and Sale
Stock
id Name size Qty
1 box1 10 100
2 box2 12 200
3 box3 14 500
4 box4 16 700
Sale
id Name size Qty
1 box1 10 1
2 box2 12 2
3 box3 14 5
4 box4 16 7
I want this result after Subtract Qty
Stock
id Name size Qty
1 box1 10 99
2 box2 12 198
3 box3 14 495
4 box4 16 693
Help!
You can JOIN the tables by id and name then simply subtract the Qty values. Added table alias name for better readability
SELECT ST.id, ST.Name, ST.size, (ST.Qty - SA.Qty) AS Qty
FROM Stock ST
INNER JOIN Sale SA ON SA.id = ST.id AND SA.Name = ST.Name
If you though join by Name is not needed then you can join only by id as
SELECT ST.id, ST.Name, ST.size, (ST.Qty - SA.Qty) AS Qty
FROM Stock ST
INNER JOIN Sale SA ON SA.id = ST.id
Update for SQLite
UPDATE Stock
SET Qty = ( SELECT ST.Qty - SA.Qty
FROM Stock ST
INNER JOIN Sale SA ON SA.id = ST.id )
WHERE id IN (SELECT id FROM Stock )
Got reference from this answer
Try this:
SELECT Stock.id, Stock.Name, Stock.size, (Stock.Qty - Sale.Qty) AS Qty
FROM Stock
INNER JOIN Sale ON Sale.id = Stock.id
Use the below query
Select table.id,table.name,table.size,sum(table.qty) from
(Select id,name,size,qty from stock
Union
Select id,name,size,qty*-1 from sale) as table group by table.id,table.name,table.size
If you want store the result In mysql you can (using the name for relation) update
update Stock as a
inner join Sale as b on a.name = b.name
set a.Qty = a.Qty -b.Qty
or using id for relation
update Stock as a
inner join Sale as b on a.id = b.id
set a.Qty = a.Qty -b.Qty
or if you simply want a select you can
select a.id, a.name, a.size, a.Qty -b.Qty as qty
from fromStock as a
inner join Sale as b on a.id = b.id
In sqlite the update with inner join is not allowed so you use the subselect
update Stock
set Qty = ( select Stock.Qty -Sale.Qty from Stock
Inner join Sale on Sale.name = Stock.name )
WHERE
EXISTS (
SELECT *
from Stock
Inner join Sale on Sale.name = Stock.name
)

Join two table. One column using SUM

I need a little help with a MySQL query.
I have two tables one table is a list of product and one table is a list of warehouses quantity
product:
product_id product_name
1 name1
2 name2
3 name3
warehouse_product
id warehouse_id product_id product_quantity
1 1 1 15
2 2 1 30
3 1 2 100
4 2 2 30
5 1 3 20
6 2 3 40
The results Im looking to get from the above data would be
product_id product_name product_quantity
1 name1 45
2 name2 130
3 name3 60
I've tried many query but it's not working. My query is:
SELECT
product_id as product_id, SUM(quantity) as quantity
FROM
(SELECT
p.product_id as product_id, wp.product_quantity as quantity
FROM
product as p
LEFT JOIN warehouse_product as wp ON p.product_id = wp.product_id
WHERE
product_active = 1)
Try this:
SELECT p.product_id, p.product_name, SUM(wp.quantity) as quantity
FROM product as p
LEFT JOIN warehouse_product as wp
ON p.product_id = wp.product_id
AND product_active = 1
GROUP BY p.product_id, p.product_name
After JOINing the two tables you need to use GROUP BY so that SUM of quantity can be calculated for each product.
select p.product_id,p.product_name,sum(product_quantity) as 'product_quantity'
from product p inner join warehouse_product whp on
whp.product_id=p.product_id group by whp.product_id
select p.product_id, p.product_name,sum(w.product_quantity)
from
product p
inner join
warehouse_product w
on
p.product_id = w.product_id
group by w.product_id
order by p.product_name;
SELECT P.productid,
P.ProductName,
Sum(W.product_quantity) As quantity
FROM Product AS P
LEFT JOIN warehouse_product AS W
ON P.productid = W.productid
GROUP BY P.ProductId , P.ProductName
SQLFiddle

Getting both max and min sum values on mysql

Good day everyone I would like a query that can give me both maximum and minimum sum values. Specifically i have the following tables:
PRODUCT
_____________________________
productID | categoryID| name|
__________|___________|_____|
1 1 "name1"
2 1 "name2"
3 1 "name3"
4 2 "name4"
5 2 "name5"
6 1 "name6"
7 2 "name7"
8 2 "name8"
AND:
PURCHASES
_____________________________
purchaseID | productID| quantity|
___________|___________|_________|
1 1 12
2 2 13
3 4 55
4 4 66
5 5 99
6 6 99
7 5 88
8 7 12
so basically i have to show the product that was bought the most and the product that was bought the least.. T have tried this:
SELECT pr.name, max(sum(p2.quantity))
FROM purchase as p2, product as pr
WHERE p2.IDproduct=pr.IDproduct
Group by p2.IDproduct desc
but I get Error Code 1111: Invalid use of group function.
For max Product
select t.name,max(t.sum1) MaxProduct
FROM
(SELECT a.name, sum(b.quantity) sum1
FROM PRODUCT a
INNER JOIN PURCHASES b
ON a.productID = b.productID
GROUP BY a.productID )t
group by t.name order by MaxProduct desc limit 1
FOR COMBINE RESULT
(select t.name,max(t.sum1) MaxProduct
FROM
(SELECT a.name, sum(b.quantity) sum1
FROM PRODUCT a
INNER JOIN PURCHASES b
ON a.productID = b.productID
GROUP BY a.productID )t
group by t.name order by MaxProduct desc limit 1)
UNION ALL
(select t1.name,min(t1.sum1) MaxProduct
FROM
(SELECT a.name, sum(b.quantity) sum1
FROM PRODUCT a
INNER JOIN PURCHASES b
ON a.productID = b.productID
GROUP BY a.productID )t1
group by t1.name order by MaxProduct asc limit 1)
SQL FIDDLE
Hacky, but it works
(
SELECT
SUM(pur.quantity) quant,
prod.name name
FROM Purchases pur
INNER JOIN Products prod
ON prod.productID = pur.productID
GROUP BY pur.productID
ORDER BY quant DESC
LIMIT 1
)
UNION
(
SELECT
SUM(pur.quantity) quant,
prod.name name
FROM Purchases pur
INNER JOIN Products prod
ON prod.productID = pur.productID
GROUP BY pur.productID
ORDER BY quant ASC
LIMIT 1
)
SQLFiddle
As I received a Cannot perform an aggregate function on an expression containing an aggregate or a subquery as an error error.
For others encountering the problem of using the SUM function inside of a MAX function, but not having the same issue as OP, based on Luv's answer, I was able to convert the following Scalar-valued function:
SELECT #MinMaxValue = MAX(SUM(ArtikelM.Omzet)/SUM(ArtikelM.Aantal))
FROM ArtikelM
INNER JOIN Klanten
ON ArtikelM.KlantenId = Klanten.KlantenId
WHERE ArtikelId = #ArtikelId
AND Klanten.KlantTypeCategorie = #KlantType
AND Klanten.KlantGrootteCategorie = #KlantGrootte
AND ArtikelM.Jaar = #Jaar
to
SELECT #MinMaxValue = MAX(selectedsum.sumx)
FROM (
SELECT SUM(ArtikelM.Omzet)/SUM(ArtikelM.Aantal) AS sumx
FROM ArtikelM
INNER JOIN Klanten
ON ArtikelM.KlantenId = Klanten.KlantenId
WHERE ArtikelId = #ArtikelId
AND Klanten.KlantTypeCategorie = #KlantType
AND Klanten.KlantGrootteCategorie = #KlantGrootte
AND ArtikelM.Jaar = #Jaar
) AS selectedsum
or if ArtikelM.Aantal could be zero
SELECT sumx =
CASE
WHEN SUM(ArtikelM.Aantal) > 0
THEN SUM(ArtikelM.Omzet)/SUM(ArtikelM.Aantal)
ELSE MIN(Leverancier.FactPrijs)
END
FROM ArtikelM
INNER JOIN Leverancier
ON ArtikelM.LevId = Leverancier.LevId
INNER JOIN Klanten
ON ArtikelM.KlantenId = Klanten.KlantenId
WHERE ArtikelId = #ArtikelId
AND Klanten.KlantTypeCategorie = #KlantType
AND Klanten.KlantGrootteCategorie = #KlantGrootte
AND ArtikelM.Jaar = #Jaar
) AS selectedsum
I think this might help out others too
Select max(product_id), min(product_id)
from Purchases Where Product_id In
(select product_id, Sum(quantity) from Purchases Group by product_id)

MYSQL count related rows in 2 tables

I have 3 tables
products table
productid productname
--------- -----------
1 product 1
2 product 2
5 product 3
10 product 4
11 product 5
12 product 6
accounts_products table
id productid accountid
-- --------- ---------
1 1 accountid 1
2 10 accountid 2
3 2 accountid3
leads_products table
id productid leadid
-- --------- ---------
1 1 leadid 1
2 5 leadid 2
3 2 leadid 3
I am trying to count how many total products are in leads_products and accounts_products tables based on the same productid's.
Expected result
Product ID Product Name Total
----------- ------------ --------
1 product 1 2
2 product 2 2
5 product 3 1
10 product 4 1
I tried so far
SELECT p.productid as 'Product ID',
p.productname as 'Product Name',
COUNT(*) as 'Total' FROM products p
INNER JOIN leads_products l ON (l.productid=p.productid)
INNER JOIN accounts_products a ON (a.productid=p.productid)
GROUP BY p.productname,p.productid
Above query counts and display higher number than expected.
I hope it makes sense.
Try this:
SELECT p.productid as 'Product ID',
p.productname as 'Product Name',
(SELECT COUNT(*)
FROM leads_products AS l
WHERE l.productid = p.productid) +
(SELECT COUNT(*)
FROM accounts_products AS a
WHERE a.productid=p.productid) AS 'Total'
FROM products AS p
http://www.sqlfiddle.com/#!2/f8472/5
Alternative approach using JOIN (better performance):
SELECT p.productid as 'Product ID',
p.productname as 'Product Name',
IFNULL(l.count, 0) + IFNULL(a.count, 0) as 'Total'
FROM products AS p
LEFT JOIN (
SELECT productid, COUNT(*) AS count
FROM leads_products
GROUP BY productid
) AS l
ON l.productid = p.productid
LEFT JOIN (
SELECT productid, COUNT(*) AS count
FROM accounts_products
GROUP BY productid
) AS a
ON a.productid = p.productid
http://www.sqlfiddle.com/#!2/f8472/33
I did it with a left join of p.products to preserve all the products then counted the products in each list and added them together. Worked first try. There's probably a billion ways to do this.
SELECT p.productid 'Product ID',
p.productname 'Product Name',
COUNT(a.accountid) + COUNT(l.leadid) total
FROM products p
LEFT JOIN accounts_products a ON p.productid = a.productid
LEFT JOIN leads_products l ON p.productid = l.productid
GROUP BY p.productid
http://www.sqlfiddle.com/#!2/f8472/37