Join Two Tables based on a third table's data - mysql

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#

Related

Mysql - How to make this work?

I have a mysql table Products.
It contains the Columns "id,product_name,product_seller,price"
I am trying to create a PHP script to Insert/Update data in the table Products using the seller name (product_seller).
The issue
I don't know what mysql query to use in order to get: A list with All the products NO matter if the seller has it or not and if the seller has the products to give me the details (id,product_name,product_seller,price).
EXAMPLE of what i want to get:
1 - apples - seller A - 12
2 - banana - -
3 - oil - -
4 - dvd - seller A - 25
The product_name must be DISTINCT
Thanks in advance!
* Query must be something like "SELECT DISTINCT product_name FROM Products and let me know where Seller A has the product, at what price, what id what product WHERE seller_name = 'seller A'...yet, show me all products, n matter if seller has it"
Seems to be a straight forward subquery to get a unique list of products then an outer join to get the seller info.
SELECT A.ID, A.Product_name, B.product_Seller, B.Price
FROM (SELECT DISTINCT ID, Product_Name FROM products) A
LEFT JOIN Products B
on A.ID = B.ID
and B.product_Seller = 'seller A'
The LEFT JOIN will ensure you return all the products and only seller information related to the items for 'SELLER A'
SQL generally operates best on data SETS. So I first generate a set of unique IDs and products and then LEFT JOIN this to the sellers product data you desire. The left join ensures we keep all the items. The filtering of the seller MUST be on the JOIN itself and not in the where clause. Otherwise the left join in essence becomes an inner as the NULLS generated from the outer join are removed.
SELECT A.ID, A.Product_name, B.product_Seller, B.Price
FROM (SELECT DISTINCT ID, Product_Name FROM products) A
LEFT JOIN Products B
on A.ID = B.ID
WHERE B.product_Seller = 'seller A'
Wouldn't get the desired result. This is because the where clause is applied after the join so the items that are not associated to the seller would be excluded. Since you want those records, you must use a left join and apply the limit on the JOIN so the items not associated to the seller are returned.
When I initially started with SQL I had trouble with this type of logic. It wasn't until I considered data in terms of "SETS" and how those sets related, that how to solve these questions became easier.
try to use the
SELECT * FROM Products_Table ;
this will obtain all the table values

SQL join with complicated condition

3 tables in database:
Supplier(id, name, address)
Product(id, name, detail)
Product_Supplier(id, productId, supplierId, quantity)
Now I want to get all products (which are supplied by all suppliers) and their quantity if they are supplied by supplier 1 (supplierId = 1). How can I do that in a single sql query?
Update: I can do that if use multiple queries: first I get product information from Product table then query Product_Supplier table with productId and supplierId. Do all in one query is shorter, but is it more efficient?
Using a LEFT OUTER JOIN will allow you to list all products, but only get the quantity for the products supplied by supplier one. You just need to use the supplierId constraint in the join condition.
SELECT Product.*,
Product_Supplier.quantity
FROM Product
LEFT OUTER JOIN Product_Supplier ON Product.id = Product_Supplier.productId
AND Product_Supplier.supplierId = 1

getting stocks on hand from two dependent tables and join the result to another table

I have a problem with regards to the stated title. I want to get the stocks_on_hand from these two tables, namely:
stocks_added
product_id quantity_added
ANK001 50
stocks_released
product_id quantity_released
ANK001 20
after getting the stocks_on_hand (result of the two tables), i want to join it to the products table:
product_id product_name price
ANK0001 ANKLET 200
Use joins and sum():
select
p.product_id, product_name, price,
coalesce(sum(quantity_added), 0) - coalesce(sum(quantity_released), 0) as stocks_on_hand
from products p
left join stocks_added a on a.product_id = p.product_id
left join stocks_released r on r.product_id = p.product_id
group by p.product_id, product_name, price
Using outer (ie left) joins means you'll get a row for every product whether or not there are rows in the stock movement tables. Using coalesce() means a default value of zero is used when there are no rows in the stock table.

Trigger multiply from two tables

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

MySQL max value from subquery and group by problem

I have three tables which we'll pretend are called products, coupons, and discounts. I have a query that attempts to pull a list of products, and runs a subquery to find ANY coupons which have a valid discount.
For example, this shows what I'm attempting:
SELECT products.id, products.name,
(
SELECT MAX(discounts.amount) FROM discounts
WHERE discounts.coupon_id = coupons.id
LIMIT 1
) as discount
FROM products
LEFT JOIN coupons ON products.id = coupons.product_id
GROUP BY products.id
My problem is that my GROUP BY is necessary for lots of other reasons. But if there are multiple coupons for each product, the "discount" gets combined in weird ways when the grouping occurs.
Let's say for a single product there are three coupons - two without any discount and one with a discount of 33%. When the group by occurs, I want to choose the highest value but by default, MySQL returns the value as 0.
Using MAX is the subquery obviously only returns the maximim value of discounts for each individual coupon. I just need to tell GROUP BY to use the max value.
I could easily use GROUP_CONCAT to return a string of all of them, but I also need to use that value in a calculation in some HAVING conditions.
Any suggestions?
I'm don't think you want or need the subquery. What does this return for you?
SELECT products.id, products.name, MAX(discounts.amount) AS discount
FROM products
LEFT JOIN coupons ON products.id = coupons.product_id
LEFT JOIN discounts ON coupons.id = discounts.coupon_id
GROUP BY products.id
You group by productid only, while the subselect actually return three values (one for each coupon of the product). I would actually expect this query to return an error. You should either move the discount one level up, or move the coupons to the subselect. An example of the first (subqueries are typically slower in MySQL):
select
p.productid,
max(d.discount) as discount
from
product p
left join coupon c on c.productid = p.productid
left join discount d on d.couponid = c.couponid
group by
p.productid