Duplicate record issue on query - mysql

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

Related

Incorrect output when filtering based on product

CREATE TABLE Cart (
Id_cart INT NOT NULL,
Id_product VARCHAR(25)
);
CREATE TABLE product (
id_product VARCHAR(25),
id_vendor INT NOT NULL
);
CREATE TABLE Orders (
Id INT,
Id_cart INT NOT NULL,
status VARCHAR(25),
order_no VARCHAR(25),
id_vendor INT NOT NULL
);
-- data
INSERT INTO Cart
(Id_cart, id_product)
VALUES
(1, 'abc002'),
(1, 'abc003')
;
INSERT INTO product
(id_product, id_vendor)
VALUES
('abc002',2),
('abc003',3)
;
INSERT INTO Orders
(Id, Id_cart,status,order_no,id_vendor)
VALUES
(1, 1, 'pending','aaa001',2),
(2, 1, 'pending','aaa002',3)
This is my sql query used to display output
Select c.id_cart,order_no,id_product from orders as o
left join (SELECT * FROM cart) c using(id_cart) where id_product = 'abc002'
//
//output
id_cart order_no id_product
1 aaa001 abc002
1 aaa002 abc002
//
//expected output
id_cart order_no id_product
1 aaa001 abc002
I want it to show only the order_no which belong id_product (abc0002) instead of showing all the order_no with the same id_cart of id_product(abc0002).
How can i do this? Anything wrong with my query? thanks.
Oof. Owie. My bones.
First things first, for the love of things please keep it somewhat clean, there's so much wrong with query it hurts my eyes. I'm not even certain what it is you're trying to achieve truth be told. From what I can see you're not using left join properly. You also have no PKs, which could've made things easier. I'm also not sure what purpose cart is serving in this statement.
Try the below and please review how and why it works if that's what you're looking for:
SELECT o.id_cart, o.order_no, p.id_product FROM orders o
LEFT JOIN product p ON o.id_vendor = p.id_vendor
LEFT JOIN cart c ON p.id_product = c.id_product
WHERE p.id_product = 'abc002'

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

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;

Combine database tables and to form into one table

I have two tables, one is Customer Detail and the other is Order Detail. Each time the Customer will order something it will store it in database. How can I find which customer orders and how many times they order and combine the customer name and orders?
CUSTOMER DETAIL:
ID NAME AGE COUNTRY
1 AAA 22 US
2 BBB 26 UK
3 CCC 25 TN
ORDER DETAIL:
ID ITEMS PRICE QUANTITY
1 APPLE 5
1 ORANGE 6
1 MANGO 4
Customer AAA has many orders.
EXPECTED RESULT:
CUSTOMERDETAIL ORDERDETAIL
AAA (HOW MANY TIMES HE ORDER AND ORDER DETAILS)
Create Table Customer (CustomerId int identity(1,1),Name varchar(20))
Create Table OrderDetail(OrderDetailId int identity(1,1), CustomerId int, Item varchar(20), Quantity int)
Insert into Customer values('AAA')
Insert into Customer values('BBB')
Insert into Customer values('CCC')
Insert into OrderDetail values(1,'Apple',10)
Insert into OrderDetail values(1,'Banana',10)
Insert into OrderDetail values(1,'Mango',10)
select y.total, x.Item,x.quantity from
(
select c.customerId as customerId, d.Item, d.quantity from customer c inner join orderdetail d
on c.customerId = d.customerId
)x
inner join
(
select customerid, COUNT(customerId)as total from orderdetail group by customerId
)y
on x.customerId = y.customerId
Suppose you have the schema like this:
Customer table (customer)
ID (Customer Id) int primary key
Name varchar(100)
Order Table (orders)
ID (Order ID) int
cusotmer_id (reference id of customer table primary key-ID) int
quality int
price float
First Count of Order against eash customer:
select count(o.customer_id) as total_order, c.* from customer c left join orders o on c.ID = o.customer_id
Orders listing against a single customer:
select c.*, o.* from customer c inner join orders o on c.ID = o.customer_id where c.ID = 1
I hope this will help you.
The following query gives what i expect.
SELECT name,items,price FROM customerdetail INNER JOIN orderdetail ON customerdetail .sno=orderdetail .id WHERE id=1 ;

MySQL UPDATE with SELECT SUM from different table

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]