Update query subtract same sale model rows from stock table? - mysql

I have two MySQL tables:
> Sale
--------------------------------------------------------
ID customer model qty
--------------------------------------------------------
1 Ali H46 1
1 aslam H46 1
1 kasif H46 1
1 umer H46 1
1 naveed H46 1
---------------------------------------------------------
> Stock
---------------------------------------------------------
ID model qty
---------------------------------------------------------
1 H46 40
1 H47 30
1 H48 20
1 H49 60
1 H50 20
---------------------------------------------------------
MySQL query I applied
UPDATE sale AS T1
INNER JOIN stock T2
ON T1.model = T2.model
SET T2.qty = (T2.qty - T1.qty)
In result in stock table only one qty update doesn't total sale qty minus from stock table.
I want all sale qty minus from stock. But my query result return 1 record update in stock.

I think you need to join to an aggregate of the Sale table:
UPDATE stock st
INNER JOIN
(
SELECT model, SUM(qty) AS qty
FROM sale
GROUP BY model
) s
ON st.model = s.model
SET
st.qty = st.qty - s.qty;
An inner join update (rather than a left join update) should be fine here, since models which had zero sales would not require updating the stock anyway.

Related

How to group rows in SQL by earliest date when are there are multiple rows with earliest date?

I am trying to come up with a query that will return the aggregate data for the earliest orders the customers have placed. What I cannot quite wrap my head around is how to construct this query when there are multiple orders placed on the same day for the earliest purchase date for customer 2.
customers
id
name
created_at
1
Sam
2019-07-12
2
Jimmy
2019-01-22
items
id
name
price
1
Watch
200
2
Belt
75
3
Wallet
150
orders
id
customer_id
item_id
created_at
1
1
1
2018-08-01
2
1
2
2018-08-11
3
2
1
2019-01-22
4
2
3
2019-01-22
5
2
2
2019-03-03
expected query
customer_id
name
first_purchase_date
n_items
total_price
1
Sam
2018-08-01
1
200
2
Jimmy
2019-01-22
2
350
I currently have the following query set up, but this query is grouping by the customer_id such that the total number of items and total price do not reflect the earliest orders.
SELECT
orders.customer_id,
customers.name AS name,
MIN(orders.created_at) AS first_purchase_date,
COUNT(*) as n_items,
SUM(items.price) as total_price
FROM orders
INNER JOIN customers
ON orders.customer_id = customers.id
INNER JOIN items
ON orders.item_id = items.id
GROUP BY
customers.id
my incorrect query
customer_id
name
first_purchase_date
n_items
total_price
1
Sam
2018-08-01
2
275
2
Jimmy
2019-01-22
3
425
I recreated the tables in a SQL Server environment but this should help...I hope as it gives you the query result you're looking for. The data is exactly the same but I'm using temporary tables so hence the # prefixes.
SELECT
#orders.customer_id,
#customer.name AS name,
#orders.created_at as first_purchase_date,
--MIN(#orders.created_at) AS first_purchase_date,
COUNT(*) as n_items,
SUM(#items.price) as total_price
FROM #orders
INNER JOIN #customer
ON #orders.customer_id = #customer.id
INNER JOIN #items
ON #orders.item_id = #items.id
inner join
(
select customer_id, name, MIN(first_purchase_date) as
first_purchase_date
from
(
SELECT
#orders.customer_id,
#customer.name AS name,
#orders.created_at as first_purchase_date,
--MIN(#orders.created_at) AS first_purchase_date,
COUNT(*) as n_items,
SUM(#items.price) as total_price
FROM #orders
INNER JOIN #customer
ON #orders.customer_id = #customer.id
INNER JOIN #items
ON #orders.item_id = #items.id
group by #orders.customer_id,#customer.name, #orders.created_at
)base
group by customer_id, name
) firstorders
on
#customer.id = firstorders.customer_id
and
#customer.name = firstorders.name
and
#orders.created_at = firstorders.first_purchase_date
group by
#orders.customer_id,#customer.name, #orders.created_at

MySQL How to get the row with max date when joining multiple tables?

My goal is the get a list of current prices and prices at the time of whatever date is given. The price as of today is always product.price. Each time a new price is set, an entry is added to product_audit and revinfo.
If we are looking for what the prices were on 2020-11-31, it would return:
num CurrentPrice OldPrice
--------------------------------------
1001 100 175
1030 110 100
2010 150 130
EDIT FOR CLARIFICATION: My intention is to get what the price was on a specific day. So OldPrice is actually the newest entry in Product_aud/revinfo that is before or on the set date (in this case, 2020-11-31). Looking specifically at code 1001, the price was changed on 2020-08-02, 2020-09-26, and 2020-01-08. If we are looking at 2020-11-31, that means it should grab 2020-09-26 because it is the soonest date before then. This means the price of 1001 on 2020-11-31 was 175.
There are three tables: Product, product_audit, revinfo
Everytime the price is changed, an entry is added to product_audit with the new price and a reference to a new entry in revinfo that has the date/time. Revinfo contains entries for other audit tables mixed in.
product.id = product_audit.id
product_audit.rev = revinfo.id
product
id num price
------------------------
1 1001 100
2 1030 110
3 2010 150
product_audit
id rev price
------------------------
1 1 200
1 3 175
1 6 100
2 2 100
2 7 110
3 4 130
3 5 120
3 8 150
revinfo
id timestamp
-------------------
1 2020-08-02
2 2020-09-25
3 2020-09-26
4 2020-11-12
5 2020-12-20
6 2021-01-08
7 2021-01-09
8 2021-01-23
Of course this just returns the oldest price from product_audit:
SELECT product.num, product.price AS CurrentPrice, product_audit.price AS OldPrice
FROM product
LEFT JOIN product_audit ON product_audit.id = product.id
LEFT JOIN revinfo ON revinfo.id = product_audit.rev
WHERE rev.timestamp <= "2020-11-31"
GROUP BY product.id
I tried nesting joins like this based on some stuff I was reading, but quickly realized it still wasn't going to get the right price:
SELECT product.id, product.num, product.price AS CurrentPrice, revisions.price AS OldPrice
FROM product
LEFT JOIN (SELECT product_audit.id AS id, product_audit.price AS price, MAX(revinfo.timestamp) AS timestamp
FROM product_audit
LEFT JOIN revinfo ON product_audit.rev = revinfo.id
WHERE revinfo.timestamp <= $DATE{Date}
GROUP BY product_aud.id) AS revisions ON revisions.id = product.id
I can't seem to think of how to get to that last step. Some sort of WHERE timestamp = (SELECT...) maybe? But I haven't been able to figure that out.
Also, just a heads up, I'm limited to statements that start with SELECT because of permissions. I can't add functions or anything like that.
I had to assume how we were getting the "old" price, and my assumption was that you wanted the "earliest" revision record, so I used Row_number and a derived table to get that record and then use it in the join constraint for the revision table... not exactly sure what your logic is, but here is a fiddle with the resultset that matches your "desired results"
SELECT product.num, product.price AS CurrentPrice, product_audit.price AS OldPrice
FROM product
LEFT JOIN (select p.price, p.id, p.rev,
ROW_NUMBER() over (partition by p.id order by p.rev asc) as rn
From product_audit p
) AS product_audit ON product_audit.id = product.id
and product_audit.rn = 1
LEFT JOIN revinfo ON revinfo.id = product_audit.rev
WHERE revinfo.timestamp <= '2020-11-31';
https://www.db-fiddle.com/f/fbvrgo2gRLoBPhgwQnuvY9/3
WITH cte AS ( SELECT product.num,
product.price CurrentPrice,
product_audit.price OldPrice,
ROW_NUMBER() OVER (PARTITION BY product.num
ORDER BY revinfo.`timestamp` DESC) rn
FROM product
JOIN product_audit ON product_audit.id = product.id
JOIN revinfo ON revinfo.id = product_audit.rev
WHERE revinfo.`timestamp` <= #date
)
SELECT num, CurrentPrice, OldPrice
FROM cte
WHERE rn = 1;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=a276ec8ad89e3c2f3aaeee411072fa3e

How to get right sum from inner join in mysql

I have two tables one is orders and second is order_product in which I have to find out orders count, product count, totalamount in corresponding to store using store id from which I have successfully find out the orders count and product count but my totalamount is not coming correct.
orders:
...........................
order_id or_total_amt
...........................
1 10
2 10
3 10
order_product
.................................
op_id op_order_id st_id
.................................
1 1 1
2 2 2
3 3 1
4 3 1
I want below output but my totalamount value is coming wrong it is coming 30,but the correct value is 20 which i have mentioned in the right output below.
output which i want:
.........................................
st_id orders product totalmount
.........................................
1 2 3 20
2 1 1 10
I have tried the below query which is giving 30 value of totalamount which is wrong.
SELECT `op_st_id`,count(distinct orders.`order_id`)as orders,count(order_product.op_pr_id) as product
,sum(orders.or_total_amt) as totalamount from orders
inner JOIN order_product on orders.order_id=order_product.op_order_id
group by `op_st_id`
SELECT
`st_id`,
count(DISTINCT orders.`order_id`) AS orders,
count(order_product.op_id) AS product,
count(DISTINCT orders.`order_id`)*(sum(orders.or_total_amt)/count(order_product.op_id)) AS totalamount
FROM
orders
INNER JOIN order_product ON orders.order_id = order_product.op_order_id
GROUP BY
`st_id`

SQL select from tables

I've got tables:
Table1= USER_ID ITEM_ID
1 12
1 13
2 12
3 12
3 1
3 2
etc..
And second table:
Products = ITEM_ID PRICE
1 1.3
2 0.1
4 22
12 33
13 45
It is just example. How can I get ID's of clients who paid more than average order value?
I tried many times, but I always get errors.
You can do a JOIN between the tables and comparing the average price with specific user price paid like
select t1.user_id
from table1 t1
join products p on t1.item_id = p.item_id
group by t1.user_id
having p.price > avg(p.price);

How to calculate the difference between purchase and sale quantity?

How can I calculate the difference between the purchase and sale quantity in one query using Ms Access database?
My data, for example, looks like this:
ProductId Type Quantity
1 Purchase 24
1 Sale 1
How would I get the difference of (24-1=23) in one query?
I suppose you have the database name [DB-NAME].
and Columns and rows are something like.
[Table1]
ProductID Quantity Purchase Sale
----------- --------- --------- --------
1 1 24 1
2 100 50 10
If you want to calculate the [Purchase] - [Sale] for a specific Product id Use:
( Select (Purchase - Sale) AS MyNumber FROM[DB-Name].[Table1] WHERE (ProductID=1))
//where 1 is your product id
The result table will be
MyNumber
--------
23
if you want to calculate the totals for all [ProductID] Use:
(Select (SUM(Purchase) - Sum(Sale)) AS MyNumber FROM[DB-Name].[Table1] )
The result table will be
MyNumber
--------
63
You can self-join the table:
SELECT p.productId, (p.quanity - COALESCE(s.quantity, 0)) difference
FROM table p
LEFT JOIN table s
ON p.type = 'Purchase' AND s.type = 'Sale' AND p.productId = s.productId