ON clause in SQL join-does order matter? - mysql

Are these two same?
- SELECT p.name,o.order_time FROM ORDERS o INNER JOIN PRODUCTS p on **o.product_id=p.id**;
- SELECT p.name,o.order_time FROM ORDERS o INNER JOIN PRODUCTS p on **p.id=o.product_id**;
And are these two the same thing:
- SELECT p.name,o.order_time FROM ORDERS o LEFT JOIN PRODUCTS p on **o.product_id=p.id;**
- SELECT p.name,o.order_time FROM ORDERS o LEFT JOIN PRODUCTS p on **p.id=o.product_id;**

Yes, first 2 queries are exactly same in terms of performance and result. In addition to that, first 2 queries is same as below query,
SELECT p.name,o.order_time FROM PRODUCTS p INNER JOIN ORDERS o on p.id=o.product_id;
Which in turn is same as,
SELECT p.name,o.order_time FROM PRODUCTS p INNER JOIN ORDERS o on o.product_id=p.id;
Note: the order of inner join tables is swapped as well.
3rd and 4th are same as well in terms of performance and result. You can't swap the order of table here, unless dataset guarantees same result.
Based on the dataset, first 2 queries can yield same or different result than last 2 queries.
Reason is = is commutative, it means a=b is same as b=a. Extending it further, just INNER JOIN is also commutative.

Related

Subtract count from left join and inner join in SQL

I want to merge two tables and subtract the number of orders in resulting table from left join from the resulting table in inner join.
This is what I have done but I do not know if this is correct or how to proceed?
WITH t1 AS (
SELECT *
FROM orders
LEFT JOIN food ON orders.id = food.id
),
t2 AS (
SELECT *
FROM orders
INNER JOIN food ON orders.id = food.id
)
SELECT
/* now what? */
Now I want to subtract number of rows in two tables.
I do not know how to proceed, should I join tables again and do subtraction, is there an easier way?
You don't even need two separate queries to answer your question. The only difference in result set between the left and inner joins is that the former will retain order records which do not map. So, you may simply write:
-- query #3
SELECT *
FROM orders o
LEFT JOIN food f
ON f.id = o.id
WHERE f.id IS NULL;
If you combine the result set from above with the inner join query #2, you will get the total left join query #1 result set without the WHERE clause.
So count(query #1) = count(query #2) + count(query #3)

What is the difference between JOIN and simple SELECT in MySQL?

I have two mySQL statements. First is:
SELECT o.OrderID, c.CustomerName, o.OrderDate
FROM Customers AS c, Orders AS o
WHERE c.CustomerID=o.CustomerID;
The second is:
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID;
Both produce the same result, but second doesn't contain reference on Customers table in FROM request.
My question is - what is the difference between these two sql statements? In which cases should I use JOIN and in which cases should I use simple SELECT from two tables?
They are the same except the second is easier to read, so you should use that one.
Those JOIN are different, although the result are the same.
The First one is CROSS JOIN and adds the condition in where, which is implicit CROSS JOIN
The second one is INNER JOIN
If you want to connect two tables I would use INNER JOIN instead of CROSS JOIN Because the intention of the inner join table is clearer

How to count from a single table whilst performing multiple joins

I was asked the following question:
Find the 3 vendors that supply our most famous products by number of units sold, not number of units ordered. Rank them first to third.
The database used is the online classicmodels db: http://mysqltutorial.org//tryit/
This is what I have done, I cannot seem to count the payments only and group by vendors. The count I get back is a product of all the joins.
SELECT p.productvendor FROM products AS p
INNER JOIN orderdetails AS od ON p.productcode = od.productcode
INNER JOIN orders AS o ON o.ordernumber = od.ordernumber
INNER JOIN customers AS c ON c.customernumber = o.customernumber
INNER JOIN payments AS py ON py.customernumber = c.customernumber
GROUP BY p.productvendor
ORDER BY COUNT(p.productvendor) DESC
LIMIT 3
Try to break the problem into smaller queries and then try to optimize the joins.
select count(p.productvendor) as product_count, p.productvendor from (JOINS) group by p.productvendor
-- this should give count by vendor. you can use sum(orderdetails.qty) also in case you
So the problem is reduced to be in the JOINS
JOINS ( has to be a collection of individual product sales)

Using two inner join tables

I have come up with two queries, both use an inner join on two different tables.
Query 1
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT, PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY, PRODUCTS.PRICESELL, CATEGORIES.NAME AS CATEGORY
FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORY = CATEGORIES.ID;
Query 2
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT, PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY, PRODUCTS.PRICESELL,STOCKCURRENT.UNITS AS UNIT FROM PRODUCTS INNER JOIN STOCKCURRENT ON STOCKCURRENT.PRODUCT = PRODUCTS.ID;
Both queries run fine on their own, when I try to use both inner joins together I get errors. This is what I came up with on my own. I'm having trouble understanding the syntax to achieve this.
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT,
PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY,
PRODUCTS.PRICESELL,STOCKCURRENT.UNITS AS UNIT FROM PRODUCTS INNER JOIN
STOCKCURRENT ON STOCKCURRENT.PRODUCT = PRODUCTS.ID, CATEGORIES.NAME AS
CATEGORY FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORY =
CATEGORIES.ID;
Thank you.
Your attempted query has several syntax problems. Assuming you just want to join together the three tables, you may try the following query:
SELECT
p.CODE,
p.REFERENCE,
p.TAXCAT,
p.DISPLAY,
p.NAME,
p.PRICEBUY,
p.PRICESELL,
s.UNITS AS UNIT,
c.NAME AS CATEGORY
FROM PRODUCTS p
INNER JOIN STOCKCURRENT s
ON s.PRODUCT = p.ID
INNER JOIN CATEGORIES c
ON p.CATEGORY = c.ID;
Note that I introduced table aliases here. These aliases can be used elsewhere in the query to avoid having to repeat the entire table name.
By the way, I can also see taking a union of your two original queries. But without expected output, it was not entirely clear what you want.

Inner Join for list of records NOT in a second table (NOT Inner Join)

I have a table let's call it products with a list of Manufacturers and Products.
I have a second table let's call it Customer, Orders.
I can do a join to make a list of all the items from each manufacturer the customer ordered doing an Inner Join. Yet trying to do an Inner Join for the items they did not fails.
I tried an Inner Join with 'Orders.Product != Products.Product' but that only works where the Customer has one order. Once there is more than one order I get the same list I would have doing an Inner Join. Any thoughts? I'll try to make a SqlFiddle tonight but was hoping a quick description might help a MySql / Join expert who has done 'NOT Inner Join'before...
It is called an anti join, you can use left join with is null check:
select p.*
from products p
left join orders o on p.Product = o.Product
where o.product is null