three tables:
Customers (id_cus, cli_name, ...)
Products (id_pro, pro_name, ...)
Orders (id_cus, id_pro)
Table Orders is relation between Customers and Products.
Question is: How to get Customers (id_cus) who choose only specific product.
Example: Product A (id_pro= 100) and want all Clients customers who only bought this Product A, not Product A and Product B. Only Product A (id_pro = 100).
SELECT `id_cus` from `Orders` where `id_pro=100;
This give me all Customers who have ever bought Product A (and maybe Product B, C too).
Sorry, no idea.
Take a look to EXISTS
Simply:
SELECT o.id_cus
FROM orders o
WHERE o.id_pro = 100
AND NOT EXISTS (SELECT * from orders o2 where o2.id_cus = o.id_cus AND o2.id_pro != 100)
You can use aggregation for this:
select o.id_cus
from orders o
group by o.id_cus
having min(o.id_pro) = max(o.id_pro) and min(o.id_pro) = 100;
Related
I have 3 tables, for the sake of this exercise we'll call them: Products, Price, and Discount. I'm trying to join Products and Price tables, only if the ProductID is found in Discount.ProductID (ProductID column within the Discount table).
Products:
ProductID
Size
Color
Ref#
A1234
Small
Blu
0C94
B5678
Med
Red
1D96
Price:
Ref#
Base
Tax
0C94
3.48
0.96
Discount:
ProductID
List
Site
A1234
Two
Three
I'm familiar with joins, so my code starts off as:
SELECT * FROM Product as a
left join Price as b
on a.Ref# = b.Ref#
but I've never nested a constraints within a where clause (if that's even the correct approach) based on a third table. Any advice would be greatly appreciated. The end result would be a new products table that only shows the one product, because ProductID B5678 is not in the Discount table.
Just do a 3-table join.
SELECT DISTINCT a.*, b.*
FROM Product AS a
JOIN Price AS b ON a.`Ref#` = b.`Ref#`
JOIN Discount AS c ON a.ProductID = c.ProductID
If you don't need any of the contents of the Discount table, use the exists() funtion to execute a sub query in the where clause. This will give you the fastest results.
SELECT *
FROM Product as a
left join Price as b on a.Ref# = b.Ref#
WHERE EXISTS (
SELECT *
FROM Discount as c
WHERE c.ProductID = a.ProductID
)
If however you do need one or more of the columns of Discount, do an inner join between Product and Discount, joining them on the ProductID. This will result in only the products that have discount, and then do another left join to Price to get the columns from Price into the resultset too. Do be aware though that in case multiple rows exist in Discount for the one Product row, this will result in the same product shown on multiple rows.
SELECT *
FROM Product as a
inner join Discount as c on c.ProductID = a.ProductID
left join Price as b on a.Ref# = b.Ref#
I have a pretty simple MySQL question. I have two tables, Customer and Orders. Customer table has fields (id, name) and Order has fields (id, customerID, and item).
I can find which customer bought product A and customers that bought product B with the following query in MySQL.
SELECT DISTINCT c.`id`, c.name, o.`item`, o.qty FROM `customer` as c
INNER JOIN order AS o ON (c.`Id` = o.`customerID`)
where o.`item` ="Product A"
Union
SELECT DISTINCT c.`id`, c.name, o.`item`, o.qty FROM `customer` as c
INNER JOIN order AS o ON (c.`Id` = o.`customerID`)
where o.`item` ="Product B"
How can find the difference and similarity in these two result sets?
1) I.e. Customers that bought only product A but did not by product B
2) I.e. Customers that bought both product A and B
Thank you for your assistance.
D
You can try using the LEFT OUTER JOIN to get the result.
i need to create a trigger that multiply two fields from two tables, but i have no idea of how to do it, so let's see if you can help me.
Two tables,
Products (product_name, price)
Orders (product_name (foreign key),units_ordered)
I need to add another field on table the Orders that multiply price from Products and units_ordered from Orders, so : total_price = price (from products) X units_ordered (from Orders)
Thanks in advance, and sorry for my bad english.
Regards
You don't need trigger at all. And also you don't need to add another column for the total price as it is already redundant.
If you want their total prices, just do it during the projection of records. Example
SELECT a.Product_Name,
a.Price,
b.units_ordered,
a.Price * b.units_ordered AS TotalPrice
FROM Products a
INNER JOIN Orders b
ON a.Product_name = b.Product_name
or you can create a VIEW out of your SELECT statement. Example,
CREATE VIEW ProductOrder
AS
SELECT a.Product_Name,
a.Price,
b.units_ordered,
a.Price * b.units_ordered AS TotalPrice
FROM Products a
INNER JOIN Orders b
ON a.Product_name = b.Product_name
and selecting from the view,
SELECT * FROM ProductOrder
But if you really want to add another column, still trigger is not an option. You only need to update the values for that column using UPDATE and joining of the two tables. Assuming your new column is called TotalPrice on table `Orders.
UPDATE Orders a
INNER JOIN Products b
ON a.Product_name = b.Product_name
SET a.TotalPrice = a.units_ordered * b.Price
I'm building a MySQL query but I can't seem to get it right.
I have four tables:
- customers
- orders
- sales_rates
- purchase_rates
There is a 1:n relation 'customernr' between customers and orders.
There is a 1:n relation 'ordernr' between orders and sales_rates.
There is a 1:n relation 'ordernr' between orders and purchase_rates.
What I would like to do is produce an output of all customers with their total purchase and sales amounts.
So far I have the following query.
SELECT c.customernr, c.customer_name, SUM(sr.sales_price) AS sales_price, SUM(pr.purchase_price) AS purchase_price
FROM orders o, customers c, sales_rates sr, purchase_rates pr
WHERE o.customernr = c.customernr
AND o.ordernr = sr.ordernr
AND o.ordernr = pr.ordernr
GROUP BY c.customer_name
The result of the sales_price and purchase_price is far too high. I seem to be getting double counts. What am I doing wrong? Is it possible to perform this in a single query?
Thank for your response!
It seems that the problem is that when you join the orders table to the tables with sales rates and purchase rates, you are getting the cartesian product of these two latter tables. I.e each row in these two tables are repeated once for each correponding row in the other table. The following query should solve this problem by summing the rates for each order before joining the sales rates and purchase rates to the other tables:
SELECT c.customernr, c.customer_name,
SUM(sr.sales_price) AS sales_price,
SUM(pr.purchase_price) AS purchase_price
FROM customers c
INNER JOIN orders o
ON o.customernr = c.customernr
LEFT JOIN (SELECT ordernr, SUM sales_price) AS sales_price
FROM sales_rates
GROUP BY ordernr) sr
ON sr.ordernr = o.ordernr
LEFT JOIN (SELECT ordernr, SUM(purchase_price) AS purchase_price
FROM purchase_rates
GROUP BY ordernr) pr
ON pr.ordernr = o.ordernr
GROUP BY c.customernr, c.customer_name;
It doesn't look like you are grouping by the customer. C.customerid or something like that.
I have two tables, Customers and Products. A customer can have more than one product.
I am trying to retrieve customers that do not have a specific product.
For example, 10 customers bought products A and B, another 10 customers bought A, B, and C. How can I retrieve those customers that do not have the C product?
For your current DB structure, this is what you are looking for:
select c.id, c.name, c.phone, c.address
from Customers c
where not exists (select * from products p
where p.customer_id = c.id and p.id = 'c')
However, you should consider creating a third table to store the individual purchases.
select *
FROM customer c
WHERE NOT EXISTS (SELECT 1 from products p
WHERE p.customer_id = c.id)
You should really (as suggested already by #Tony andrews and #Adrian) have a third table to store details of which customers bought which product.
Somthing like:
**Customer**
Id
Name
Address
Phone
**Product**
Id
Name
Price
**Customer_Product**
customer_id
product_id
This means you're removing redundancy from your product table. Consider what you'd need to do if a product name changed slightly - instead of updating multiple rows (as you'd have to do now), you'd only have to update 1 row, and you wouldn't need to touch your transaction history at all..