SQL join with complicated condition - mysql

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

Related

Join Two Tables based on a third table's data

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#

Need help on SQL Query with 4 tables

Currently I have the following 4 tables: customer, customer_orders_product, customer_order and customer
What I am trying to do is to run a query that could show the following columns:
order_id, product_name, quantity and order total (which is quantity *
product_price)
But I am not sure if there is any query that is capable to do so, any help on this?
Furthermore, is there any query with JOIN syntax that I could run with those 4 tables?
You just join each pair of tables according to the fields that reference each other:
SELECT co.order_id,
p.product_name,
cop.quantity,
cop.quantity * p.product_price AS total
FROM customer_order co
JOIN customer_order_product cop ON co.order_id = cop.order_id
JOIN product p ON cop.product_id = p.product_id
Incidentally, you don't need all four tables for this query - the customer details are irrelevant for your question.

Get 2 variables from tables which are connected not directly

I have these tables:
Customer = {id,firstname,last name,street,city}
Invoice = {id, customerid, total}
Item = {invoiceid, item, productid, quantity, cost}
Product = {id, name, price}
I would like to get the first name of the customer and the list of products what he bought.
I have created an sql code:
select customer.firstname, product.name from product
inner join item on item.productid = product.id
inner join invoice on invoice.id=item.invoiceid
inner join customer on customer.id=invoice.customerid
where customer.id=24
the customer.id is 24, because on this id I should get only 3 items' name.
Unfortunately, I am getting multiplication of these items.
What should I repair in my query?
I am getting multiplication of these items.
That is how relational databases work when you ask for a join. You get a Cartesian Product of the matching records.
However, MySQL has a facility that lets you put multiple values into a single field - it's called group_concat:
SELECT
customer.firstname
, GROUP_CONCAT(product.name SEPARATOR ', ')
FROM product
INNER JOIN item ON item.productid = product.id
INNER JOIN invoice ON invoice.id=item.invoiceid
INNER JOIN customer ON customer.id=invoice.customerid
WHERE customer.id=24
GROUP BY customer.id
Note the use of GROUP BY, which "merges" all rows for the same customer id into a single group, on which GROUP_CONCAT operates.

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, right ? left ? inner?

working with mySql I would like to list all purchases that customers made on a specific cathegory of products.
So, I had 3 tables: customers (idCustomer, Name) , cathegories (idCategory, CategoryName) and orders (idOrder, idCustomer, idCathegory, Qty, Price)
But I want a listing with ALL of the customers.
Not only the one who bought that specific idCategory
I thought something like:
select sum(Orders.Qty), Customers.Name
from Orders
right join Customers on Orders.idCustomer = Customer.idCustomer
where Orders.idCategory = 'Notebooks'
group by Orders.idCategory
but this statement only lists the records for customers who exists in Orders table.
And I want all of them ( the one who didnt buy, with qty =0 )
thanks in advance
Most people find left join easier to follow than right join. The logic for left join is to keep all rows in the first table, plus additional information from the remaining tables. So, if you want all customers, then that should be the first table.
You will then have a condition on the second table. Conditions on all but the first table should be in the on clause rather than a where. The reason is simple: when there is no match, then the value will be NULL and the where condition will fail.
So, try something like this:
select sum(o.Qty) as sumqty, c.Name
from Customers c left join
Orders o
on o.idCustomer = c.idCustomer and
o.idCategory = 'Notebooks'
group by c.Name;
Finally, the group by should have a relationship to the select clause.
Try this query
select sum(Orders.Qty), Customers.Name
from Customers
right join Orders on Customer.idCustomer = Orders.idCustomer and Orders.idCategory = 'Notebooks'
group by Customers.Name