Mysql: how can `natural join` using `join_condition`? - mysql

In Mysql, I found the natural join syntax is:
`table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor`,
but other join types like inner or outer join can use join_conditon, like the syntax:
`table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition`,
so how can I use join_condition in natural join? Is there some alternatives?

A natural join has an implicit join condition, equality on all columns with the same name.
If you want some other join condition, don't use a natural join. If a natural join's implicit join condition is what you want, use that. In general, it's probably easier for everyone to understand if you don't use a natural join and make your join condition explicit.

Related

Execution time taken by different SQL JOINS

Below two queries result the same result set. In first I have only used INNER JOIN and in second query mix of joins like LEFT and RIGHT JOIN. I personally prefer INNER JOIN when there is no specific task/requirement of other joins. But I just want to know that is there any difference between the below two queries in terms of performance or execution time. Is it ok to use inner join than the mix of joins?
1.
SELECT film.title, category.name, film.rating, language.name
FROM film INNER JOIN film_category ON film_category.film_id = film.film_id
INNER JOIN category ON category.category_id = film_category.category_id
INNER JOIN language ON language.language_id = film.language_id
WHERE category.name = "Sci-Fi" AND film.rating = "NC-17";
SELECT film.title, film.release_year, film.rating,category.name, language.name
FROM film LEFT JOIN language ON language.language_id=film.language_id
RIGHT JOIN film_category ON film_category.film_id = film.film_id
LEFT JOIN category ON category.category_id=film_category.category_id
WHERE film.rating="NC-17" AND category.name="Sci-Fi";
Please see this INNER JOIN vs LEFT JOIN performance in SQL Server.
However, choosing the proper join type is depending on the usecase and result set which you need to extract.
Please do not mix the different types except in this way: INNER, INNER, ... LEFT, LEFT, ... Any other combination has ambiguities about what gets done first. If you must mix them up, use parentheses to indicate which JOIN must be done before the others.
As for whether INNER/LEFT/RIGHT are identical, let me explain with one example:
SELECT ...
FROM a
LEFT JOIN b ON ... -- really INNER
WHERE b.x = 17
That WHERE effectively turns the LEFT JOIN into INNER JOIN. The Optimizer will do such. I, as a human, will stumble over the query until I realize that. So, humor me by calling it INNER JOIN.
Phrased another way, use LEFT only when the "right" table's columns are optional, but you want NULLs when they are missing. Of course, you may want the NULLs so you can say "find rows of a that are not in b:
SELECT ...
FROM a
LEFT JOIN b ON ...
WHERE b.id IS NULL -- common use for LEFT
While I have your attention, here are some notes/rules:
The keywords INNER, CROSS, and OUTER are ignored by MySQL. The ON and WHERE clauses will determine which type of JOIN is really intended.
Have you ever seen an owl turn its head nearly all the way around? That's what happens to my head when I see a RIGHT JOIN. Please convert it to a LEFT JOIN.
Though the Optimizer does not require this distinction, please use ON to specify how the tables are related and use WHERE for filtering. (With INNER, they are equivalent; with LEFT, you may get different results.)
Sometimes EXISTS( SELECT ... ) is better than a LEFT JOIN.
Optimizations vary depending on the existence of GROUP BY, ORDER BY, and LIMIT. But that is a loooong discussion.
Back to your question of which is faster, etc. Well, if the Optimizer is going to turn one into another, then those two have identical performance.

Is this a left join or right join, inner or outer?

Sitting here at work writing SQL for the first time in a while. I know all the vendiagrams of all the joins, but I was wondering what type of join I just wrote. Is this even a typical join since I'm not using a 'JOIN' keyword?
select * from table1 t, table2 a where a.column1 = -10300 AND t.column1 = a.column2;
Thanks,
k9
This performs the same as an inner join because of the "t.column1 = a.column2". If that was left out, it would be a cross apply.
Here's some more info: http://explainextended.com/2009/07/16/inner-join-vs-cross-apply/
This is what would be considered an older style inner join.
In MySQL writing JOIN unqualified implies INNER JOIN. In other words the INNER in INNER JOIN is optional.
Official documentation about JOIN here
This is an old oracle-style inner join. It will give you all rows from both tables where the column matches, which is pretty much what an inner join is.
FYI, this used to be standard practice in Oracle SQL before everything went to ANSI-standard SQL.
Its Inner join as you used Inner Join logic in Where.

Inner Join and Cross Join yielding the same result

use classicmodels;
select Orders.OrderNumber,
Customers.CustomerName, Orders.Status, orders.shippeddate,
Customers.Country
from Customers **cross join/inner join** Orders
on Customers.CustomerNumber = Orders.customerNumber
order by 1 asc
Hi all, I'm really confused as to why inner join in my query isn't really any different from the result of the cross join? I thought that cross join would result of a Cartesian product but both joins are giving me 326 rows. I've also seen somewhere that I shouldn't use non-unique data?
From the MySQL JOIN docs:
In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents
(they can replace each other). In standard SQL, they are not
equivalent. INNER JOIN is used with an ON clause, CROSS JOIN is used
otherwise.

Is the On Clause Neccessary for Left/Right Outer Joins

I have the following very simple left outer join in MYSQL:
select * from employee left join department
However, this gives me the meaningless error message
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
But if I simply add an ON clause as shown below, the query works:
select * from employee left join department on employee.departmentId = department.id;
So, is the ON clause mandatory? If I do a "Full Join", it definitely works without an ON clause, but left and right outer joins don't work unless I add an ON clause to them.
By the way there is nothing special about the 2 tables, and there is no foreign key relation between them either.
Edition:
This is the full join that works in MySql:
select * from employee full join department;
In the ANSI standard, on is required for all join types except cross join. This applies to Oracle and most other databases.
MySQL is a bit different. This is the syntax diagram in the MySQL documentation:
join_table:
table_reference [INNER | CROSS] JOIN table_factor [join_condition]
| table_reference STRAIGHT_JOIN table_factor
| table_reference STRAIGHT_JOIN table_factor ON conditional_expr
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor
That is, MySQL allows the on to be optional for join, but not left outer join or right outer join. MySQL does not support full outer join. And, to make it more confusing cross join is like join and can accept an on clause.
And, you should ignore the MySQL extensions. Always use an on clause for left, right, and inner joins. Never use an on clause for cross join. I prefer using these to the natural join (which you don't ask about), because I prefer to be explicit in the columns being used for the join.
EDIT:
According to SQL Fiddle, version 5.6 gets an error on full outer join when left outer join works. So this generates an error:
select *
from (select 1 as a) t1 full outer join
(select 2 as b) t2
on t1.a = t2.b;
This also generates an error:
select *
from (select 1 as a) t1 full join
(select 2 as b) t2;
And MySQL documentation (through 5.7) is all very clear that full join is not supported. I'm not sure why your query might have worked.
If you want that it work without ON clause, you need the same column name in the 2 tables:
department.departmentId with employee.departmentId

Are left outer joins and left joins the same? [duplicate]

This question already has answers here:
Difference between RIGHT & LEFT JOIN vs RIGHT & LEFT OUTER JOIN in SQL [duplicate]
(4 answers)
Closed 9 years ago.
I have seen joins called LEFT OUTER JOIN or RIGHT OUTER JOIN. In some places I have seen LEFT JOIN or RIGHT JOIN. I am confused by this.
I posted a question 2 days ago, but I am unable to understand the links the solutions provide.
Are these types of joins both the same, or is there some difference between the two?
There are no difference between both.
Refer visual represenation of joins
The first link they quoted gives you:
INNER JOIN: returns rows when there is a match in both tables.
LEFT JOIN / LEFT OUTER JOIN: returns all rows from the left table, even if there are no matches in the right table.
RIGHT JOIN / RIGHT OUTER JOIN: returns all rows from the right table, even if there are no matches in the left table.
FULL JOIN / FULL OUTER JOIN / OUTER JOIN: returns rows when there is a match in one of the tables.
SELF JOIN: is used to join a table to itself, as if the table were two tables, temporarily renaming at least one table in the SQL statement.
CARTESIAN JOIN: returns the cartesian product of the sets of records from the two or more joined tables.
The self join is actually not a special join. It just reflects the fact that you can join a table with itself. Doing so you must alias it in order to address the fact that it appears more than once in the same statement.
The cartesian join can be considered as an inner join without a restricting condition. Or you may view an inner join as a cartesian join with an added restriction (the join condition).
If you look at the manual page for JOIN you will see the following lines:
join_table:
table_reference [INNER | CROSS] JOIN table_factor [join_condition]
| table_reference STRAIGHT_JOIN table_factor
| table_reference STRAIGHT_JOIN table_factor ON conditional_expr
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor
The bold line clearly shows that the keyword OUTER is optional.
In MySQL syntax, LEFT OUTER JOIN and LEFT JOIN are identical: (from http://dev.mysql.com/doc/refman/5.0/en/join.html)
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor
Note that the OUTER keyword is optional for LEFT/RIGHT JOIN.
LEFT and RIGHT joins are both outer joins. I believe there are some flavors of SQL that may require the OUTER keyword, but MySQL does not. That is to say that at times LEFT JOIN may not be valid.
I am working in SQL Server and as per my usage and experience there is absolutely no difference between LEFT JOIN and LEFT OUTER JOIN. The same is true for RIGHT JOIN and RIGHT OUTER JOIN. When you use LEFT JOIN keyword in SQL Server, it means LEFT OUTER JOIN only.
So as per my opinion its the generic rule which is same for all database engines.
see here and here