LEFT [OUTER] JOIN
This is the fifth part of a series of articles showing the basics of SQL. In this article we take a look at some of the common joins, both ANSI and non-ANSI, available in SQL.
- Setup
- Introduction
- [INNER] JOIN ... ON
- LEFT [OUTER] JOIN
- RIGHT [OUTER] JOIN
- FULL [OUTER] JOIN
- CROSS JOIN
- NATURAL JOIN
- [INNER] JOIN ... USING
- Additional Joins
Related articles.
You can perform all these queries online for free using SQL Fiddle .
The examples in this article require the following tables to be present.
These tables are a variant of the EMP and DEPT tables from the SCOTT schema. You will see a lot of Oracle examples on the internet using the tables from the SCOTT schema. You can find the original table definitions in the "$ORACLE_HOME/rdbms/admin/utlsampl.sql" script.
Joins are used to combine data from multiple tables to form a single result set. Oracle provides two approaches to joining tables, the non-ANSI join syntax and the ANSI join syntax, which look quite different.
The non-ANSI join syntax has historically been the way you perform joins in Oracle and it is still very popular today. The tables to be joined are listed in the clause and the join conditions are defined as predicates in the clause. Even if you don't like it, you are going to have to get used to it as there is a lot of code out there that still uses it. If you are not familiar with the syntax you will struggle to bug fix any existing code and some of the examples on the internet will look rather mysterious to you.
The ANSI join syntax was introduced in Oracle 9i . It has a number of advantages over the original syntax.
- It reads more like English, so it is much clearer.
- The tables and join conditions are all kept together in the clause, so the clause only contains filters, not join conditions.
- The syntax makes it difficult, if not impossible, to forget to include the join condition.
- Filters on columns from outer joined tables are handled in a much clearer manner.
- It is more portable, being supported by a number of relational database engines.
- It provides some functionality that is not supported directly by the non-ANSI join syntax, without using significantly more effort.
Despite all these advantages, many Oracle developers still use the non-ANSI join syntax. Partly this is just because of habit. Partly this is because the Oracle optimizer transforms most ANSI join syntax into the non-ANSI join syntax equivalent before it is executed.
For a beginner, my personal opinion is you should focus on the ANSI join syntax, but be aware of the non-ANSI equivalent. In this article I will show the ANSI and non-ANSI syntax for each example, where relevant.
Some join methods are more popular than others, so initially focus your attention on those you are most likely to see. The most common joins you are likely to see in code are the following.
-
The following are less common.
-
The following are very rare at this point.
-
If a word is surrounded by "[]" it means it is an optional keyword. Without any other qualifier, a join is an inner join, so using the keyword is redundant. If the join includes the words , or , it is by definition an outer join, so the keyword is redundant. The choice to include or exclude these words is really personal preference, so follow the standard in your company, or do what feels right to you.
With all that in mind, lets have a look at some examples.
An combines data from two tables where there is a match on the joining column(s) in both tables.
Remember, the keyword is optional. In the examples below, we are returning the DEPARTMENT_NAME and the EMPLOYEE_NAME for each employee. The OPERATIONS department has a DEPARTMENT_ID of 40, so it is not removed by the filter condition, but there are no employees in this department, so there is no match and it is not returned in the result set.
Here is an example of an ANSI .
Here is the non-ANSI equivalent of the previous statement.
A returns all valid rows from the table on the left side of the keyword, along with the values from the table on the right side, or NULLs if a matching row doesn't exist.
