MySQL UPDATE with SELECT SUM from different table - mysql

I have two tables:
ITEMS with quantities and unit_price (id | name | order_id | qt | unit_price)
and table ORDERS.
I want to UPDATE table orders and place in orders.total_price sum of multiplications qt*unit_price for the same orders to get total price of the order.
The SELECT query on the items table is quite simple and works fine giving sums for all items within the same order_id:
SELECT SUM(items.qt*items.unit_price) from items GROUP by items.order_id
but I can't insert this value in my ORDERS table. I couldn't make this work:
UPDATE orders, items SET orders.total_price = (SELECT SUM(items.qt*items.unit_price)
FROM items GROUP BY items.order_id) WHERE orders.id = items.order_id
it returns "Subquery returns more than 1 row"
I found a very similar question here but the answer didn't work for me as well:
UPDATE orders SET orders.t_price = (SELECT SUM(items.qt*items.unit_price) from items WHERE orders.id = items.order_id)

You can UPDATE with JOINing the two tables:
UPDATE Orders o
INNER JOIN
(
SELECT order_id, SUM(qt * unit_price) 'sumu'
FROM items
GROUP BY order_id
) i ON o.id = i.order_id
SET o.total_price = i.sumu
[WHERE predicate]

Related

Duplicate record issue on query

This is my sample data
-- schema
CREATE TABLE Cart (
Id_cart INT NOT NULL,
Id_product VARCHAR(25)
);
CREATE TABLE Orders (
Id INT,
Id_cart INT NOT NULL,
Id_vendor INT NOT NULL,
status VARCHAR(25),
order_no VARCHAR(25)
);
-- data
INSERT INTO Cart
(Id_cart, Id_product)
VALUES
(1, 'abc002'),
(1, 'abc003')
;
INSERT INTO Orders
(Id, Id_cart,Id_vendor,status,order_no)
VALUES
(1, 1,1, 'pending','aaa001'),
(2, 1,2, 'pending','aaa002')
;
I use this query to show record.
Select c.id_cart,order_no,id_product from cart as c
left join (SELECT id_cart,status,order_no FROM orders) o using(id_cart)
The result i get
id_cart order_no id_product
1 aaa002 abc002
1 aaa001 abc002
1 aaa002 abc003
1 aaa001 abc003
The result i expected
id_cart order_no id_product
1 aaa001 abc002
1 aaa002 abc003
Anything wrong with my query? How can i eliminate the duplicate record?
Let's say i added a column vendor_id to the orders table. Each order_no belong to one vendor and an id_cart will belong to many supplier. When i am trying to display my product, i want to display order_no and my id_product.
E.g. I have a cart belong to two order
an order belong to vendor A (1) and consist of product A and B.
an order belong to vendor B (2) and consist of product C and D.
During display the output should be
order_no | product_id
order1 | A
order1 | B
order2 | C
order2 | D
Now my problem is each order_no will be loop for each product_id. How can i overcome this?
You want to show cart products along with their orders. Carts contain products from different vendors for which exist separate orders. So join the product table to the cart in order to know the vendor and only then join the order table.
select
id_cart,
o.order_no,
id_product
from cart c
join product p using (id_product)
join orders o using (id_cart, id_vendor);
If you also want cart products for which no order has been written yet, make the orders join an outer join.
UPDATE: As you are reporting an issue with "Unknown column 'id_vendor' in 'from clause'", here is the query with ON clauses instead:
select
c.id_cart,
o.order_no,
c.id_product
from cart c
join product p on p.id_product = c.id_product
join orders o on o.id_cart = c.id_cart and o.id_vendor = p.id_vendor;
Simple add GROUP BY to your sql Query
SELECT c.id_cart,order_no,id_product FROM cart AS c
left join (SELECT id_cart,status,order_no FROM orders) o using(id_cart) GROUP BY o.order_no
Example :- http://sqlfiddle.com/#!9/b6b118/6/0

Need help on query sum total quantity show wrong output

Process:
When user buy item and check out then there's cart and cart items table to store the transaction.
1 cart_id have many item which stored in cart items table.
After purchase succeed, then will generate a purchase order id and stored in purchase order table .
In purchase order table, id_cart and status will be stored.
From here, i am trying to calculate quantity based on id_product or id branch or etc from the purchase made.
There is receiving and ordered quantity field, which in some cases quantity received field might be null, so i will take ordered quantity value.
This is my query
SELECT id_product,sum(DISTINCT(COALESCE(received_qty, quantity)))
FROM (SELECT C.id_cart,C.received_qty,C.quantity , P.id_product,
PO.id_purchase_order, PO.status
FROM (SELECT * FROM cart_items WHERE id_cart IN (SELECT id_cart FROM purchase_orders)) AS C
LEFT JOIN products as P on p.id_product = c.id_product
LEFT JOIN purchase_orders AS PO ON C.id_cart = PO.id_cart ) AS A
GROUP By A.id_product
Table data
The cart id in will be duplicated based on product's supplier. Because need to track and send separately to supplier.
Result
By right the product id for 1212 should be 1 and 1223 is 2, total qty =3.
What's wrong with my query ?
Your outer joins seem to cause multiplication of your data, but there are so many unnecessary layers of fluff in your query that I cant make it out exactly.
How about just this:
SELECT id_product, sum(COALESCE(received_qty, quantity)) AS Nmbr
FROM cart_items
GROUP BY id_product
If you want to make sure the cart is in your purchase_orders:
SELECT c.id_product, sum(COALESCE(c.received_qty, c.quantity)) AS Nmbr
FROM cart_items c
JOIN (SELECT DISTINCT id_cart FROM purchase_orders) p ON p.id_cart = c.id_cart
GROUP BY c.id_product

SQL query to get a result based on count of records in other table

I have 3 tables in MySQL DB: orders, items and item_to_orders. That last table, item_to_orders, ties orders and items together by item_id and order_id indexes.
orders:
order_id order_name order_status
1 Test 0
2 Test2 1
items:
item_id item_name
1 item1
2 item2
item_to_order
order_id item_id
1 1
2 2
I need to select one item_id from items table, that has no orders with order_status=0 assigned to it in item_to_order table. It can have any other orders (where order_status != 0) assigned to it or no orders at all.
Updated: I was trying to use this query, but it seems that it doesn't give me all the correct results (I added LIMIT because I need only 1 item of that kind).
SELECT ei.item_id from items ei
LEFT JOIN items_to_orders eio ON ei.item_id=eio.item_id
WHERE NOT EXISTS
(select * from orders o where o.order_id = eio.order_id and o.order_status=0)
ORDER BY ei.item_id LIMIT 1
You approach is already quite fine. EXISTS is the way to go. Only you don't want to see item/order combinations for which not exists a certain order type, but items. So you must put items_to_orders inside the subquery, so you select from items for which not exists the order type.
select item_id
from items i
where not exists
(
select *
from items_to_orders ito
join orders o on o.order_id = ito.order_id
where ito.item_id = i.item_id
and o.order_status = 0
);
Try this query
SELECT i.item_id, i.item_name
FROM order o
JOIN item_to_order ir ON(ir.order_id = o.order_id)
JOIN items i ON(i.item_id =ir.item_id)
WHERE o.order_status!=0
GROUP BY i.item_id

mySQL SQL joined table then find rows with duplicates

I have two tables:
Orders
orders_ID
orderDate
Order Details
product_ID
order_ID
quantity
Products
product_ID
productName
productDescription
I want to find all the records in the Order Details of product_ID 1 and 4 (so trying to see when one order contains both of these products). So ran this code - the INNER JOIN creates a results table that contains only orders that contain product 1, 4, or 1 and 4.
Then I want to count all of the "Order Details".order_ID duplicates - these would be all of the orders that contain 1 and 4 (note- trivial database - a given order doesn't contain more than 1 of any product).
Here is my code - doesn't quite work - any thoughts?
SELECT order_ID, COUNT(*) TotalCount
FROM
(SELECT * FROM Orders o INNER JOIN "Order Details" od ON o.order_ID = od.order_ID
WHERE od.product_ID = 1 OR od.product_ID = 4)
GROUP BY order_ID
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
Thanks- I looked through the forum but didn't see anything that helped me - been trying for some time.
I think what you want is a JOIN:
select prod1.order_id from `Order Details` prod1 JOIN `Order Details` prod4 on prod1.order_ID=prod2.order_ID where prod1.product_ID=1 and prod2.product_ID=4;

Inverse of Inner join (Intersect) with multiple foreign keys

Hi I want to get opposite of intersect from two tables.
I have a sale table and purchase table. What I want to do is get all purchases ids where not included in the sales table.
sale table
sale_id (pk)
product_id (fk)
purchase_id (fk)
purchase table
product_id (fk)
purchase_id (pk)
SELECT DISTINCT purchase_id
, product_id
FROM
purchase
INNER JOIN sale
USING (purchase_id, product_id);
Here is an example:
If I run the above code, this will be the result.
purchase_id product id
1 1
1 2
1 4
2 1
2 3
Now I want to get:
purchase_id product id
1 3
2 2
In short I want to get inverse of above code. Thanks in advance.
Okay, I think I understand better now.
This should return any entry in purchase that have no matching entry in sales.
SELECT
`purchase`.`purchase_id`, `purchase`.`product_id`
FROM `purchase`
LEFT JOIN `sale` ON `sale`.`purchase_id` = `purchase`.`purchase_id` AND `sale`.`product_id` = `purchase`.`product_id`
WHERE
`sale`.`sale_id` IS NULL
ORDER BY
`purchase`.`purchase_id`, `purchase`.`product_id`
If you want to get all the purchases that have no related values in the sales table, you can use a LEFT JOIN:
select
p.purchase_id
from
purchase as p
left join sale as s on p.purchase_id = s.purchase_id
where
s.purchase_id is null;
"Unilateral" joins (LEFT JOIN, RIGHT JOIN) are useful when you want to get data from a table even if data in another related table does not exist. Of course, that means that you can filter data from one table when there's no related data in a second table.
Hope this helps.
Looking at your updated question and your comment, I think that you want all the possible combinations not used.
You'll need to split this in two steps:
First you need all the possible combinations of purchase_id and sale_id values (the "cartesian product" of both the sets).
Then you need to get all the combinations already used.
Finally you need to exclude all the combinations already used.
This can be done using subqueries.
Step 1.
select distinct p.purchase_id, s.product_id from purchase as p, sale as s;
Step 2. (Your query)
select distinct
purchase_id, product_id
from
purchase as p
inner join sale as s
on (p.purchase_id = s.purchase_id and p.product_id = s.product_id);
Step 3. Put it all together
select
a.*
from
(select distinct p.purchase_id, s.product_id from purchase as p, sale as s) as a
left join (
select distinct
purchase_id, product_id
from
purchase as p
inner join sale as s
on (p.purchase_id = s.purchase_id and p.product_id = s.product_id)
) as e on (a.purchase_id = e.purchase_id and a.product_id = e.product_id)
where
e.purchase_id is null and e.product_id is null;