Using Joins

Objective

After completing this lesson, you will be able to construct rows from multiple queries.

Joins Overview

Where UNION and similar operators allow the combination of results from multiple queries as if they were a single set, it is also possible to combine data that came from multiple rows as if they were a single, continuous row.

You can use JOINs to combine data from several tables in common rows of a result set:

  • CROSS JOIN, INNER JOIN, and OUTER JOIN are the three types of JOINs.
  • The two syntax options, implicit and explicit, are available.

Cross Joins

You can use a Cross Join, also called Cartesian product, to create a result set in which each row of each partial query involved is combined with each row of the other partial queries involved.

Note

Cross join results are frequently not meaningful by themselves. For example, it is not helpful to list out every car as being registered simultaneously by every owner.

CROSS JOIN: Explanation

Each row of the left table is connected to each row of the right table.

No logical condition is required with the CROSS JOIN clause.

Diagram showing the cross join.

Joins may be specified with two different syntaxes: implicit and explicit. Although you will probably encounter implicit joins, the explicit syntax allows for more control and is considered more correct. While a few implicit examples will be shown, you should focus on the explicit syntax.

CROSS JOIN with Implicit Syntax

Each row of a table is connected to each row of the other table.

The result set contains 10 * 20 = 200 rows.

Code Snippet
12
SELECT * FROM Owner, Car;
OWNERIDNAMEBIRTHDAYCITYCARIDPLATENUMBERBRANDCOLORHPOWNER
H01Ms T1934-06-20WieslochF01HD-V 106Fiatred75H06
H02Ms U1966-05-11HockenheimF01HD-V 106Fiatred75H06
H03SAP AG?WalldorfF01HD-V 106Fiatred75H06
 
H01Ms T1934-06-20WieslochF02HD-VW 4711VWblack120H03
H02Ms U1966-05-11HockenheimF02HD-VW 4711VWblack120H03
H03SAP AG?WalldorfF02HD-VW 4711VWblack120H03
H01Ms T1934-06-20WieslochF03HD-JA 1972BMWblue184H03
H02Ms U1966-05-11HockenheimF03HD-JA 1972BMWblue184H03
H03SAP AG?WalldorfF03HD-JA 1972BMWblue184H03
H10Mr Z1986-02-03LadenburgF20?Audigreen184?

CROSS JOIN with Explicit Syntax

Each row of a table is connected to each row of the other table.

The result set contains 10 * 20 = 200 rows.

Code Snippet
12
SELECT * FROM Owner CROSS JOIN Car;
OWNERIDNAMEBIRTHDAYCITYCARIDPLATENUMBERBRANDCOLORHPOWNER
H01Ms T1934-06-20WieslochF01HD-V 106Fiatred75H06
H02Ms U1966-05-11HockenheimF01HD-V 106Fiatred75H06
H03SAP AG?WalldorfF01HD-V 106Fiatred75H06
 
H01Ms T1934-06-20WieslochF02HD-VW 4711VWblack120H03
H02Ms U1966-05-11HockenheimF02HD-VW 4711VWblack120H03
H03SAP AG?WalldorfF02HD-VW 4711VWblack120H03
H01Ms T1934-06-20WieslochF03HD-JA 1972BMWblue184H03
H02Ms U1966-05-11HockenheimF03HD-JA 1972BMWblue184H03
H03SAP AG?WalldorfF03HD-JA 1972BMWblue184H03
H10Mr Z1986-02-03LadenburgF20?Audigreen184?

CROSS JOIN and WHERE Clause

A WHERE clause may be specified to reduce the rows returned from a join.

Code Snippet
123
SELECT * FROM Owner, Car WHERE HP > 250;
Code Snippet
123
SELECT * FROM Owner CROSS JOIN Car WHERE HP > 250;
OWNERIDNAMEBIRTHDAYCITYCARIDPLATENUMBERBRANDCOLORHPOWNER
H01Ms T1934-06-20WieslochF06HD-VW 1999Audiyellow260H05
H02Ms U1966-05-11HockenheimF06HD-VW 1999Audiyellow260H05
H03SAP AG?WalldorfF06HD-VW 1999Audiyellow260H05
H04HDM AG?HeidelbergF06HD-VW 1999Audiyellow260H05
H05Mr V1952-04-21LeimenF06HD-VW 1999Audiyellow260H05
H06Ms W1957-06-01WieslochF06HD-VW 1999Audiyellow260H05
H07IKEA?WalldorfF06HD-VW 1999Audiyellow260H05
H08Mr X1986-08-30WalldorfF06HD-VW 1999Audiyellow260H05
H09Ms Y?1986-02-10SinsheimF06HD-VW 1999Audiyellow260H05
H10Mr Z1986-02-03LadenburgF06HD-VW 1999Audiyellow260H05

Cross Joining Multiple Tables

Cross joining multiple tables quickly increases the number of result rows.

The result set contains 10 * 20 * 3 = 600 rows.

Code Snippet
12
SELECT * FROM Owner, Car, Stolen;
Code Snippet
12
SELECT * FROM Owner CROSS JOIN Car CROSS JOIN Stolen;
OWNERIDNAMEBIRTHDAYCITYCARIDPLATENUMBERBRANDCOLORHPOWNERPLATENUMBERREGISTERED_AT
H01Ms T1934-06-20WieslochF01HD-V 106Fiatred75H06HD-VW 19992012-06-20
H01Ms T1934-06-20WieslochF01HD-V 106Fiatred75H06HD-V 1062012-06-01
H01Ms T1934-06-20WieslochF01HD-V 106Fiatred75H06HD-Y 3332012-05-21
H01Ms T1934-06-20WieslochF02HD-VW 4711VWblack120H03HD-VW 19992012-06-20
H01Ms T1934-06-20WieslochF02HD-VW 4711VWblack120H03HD-V 1062012-06-01
H01Ms T1934-06-20WieslochF02HD-VW 4711VWblack120H03HD-Y 3332012-05-21
H02Ms U1966-05-11HockenheimF01HD-V 106Fiatred75H06HD-VW 19992012-06-20
H02Ms U1966-05-11HockenheimF01HD-V 106Fiatred75H06HD-V 1062012-06-01
H02Ms U1966-05-11HockenheimF01HD-V 106Fiatred75H06HD-Y 3332012-05-21
H10Mr Z1986-02-03LadenburgF20?Audigreen184?HD-Y 3332012-05-21

You can also cross join a table with itself.

Note

In general, a cross join can quickly lead to a very large result set because its cardinality (number or rows) equals the product of the cardinalities of the queries of which it is comprised. It can be easy to produce a cross join by mistake, because its syntax looks very similar to that of the inner join.

Table Aliases

Different tables can have columns with the same name. This can lead to ambiguities when joining such tables. For example, when a column name that appears in two or more of the tables involved is used in the projection list, the WHERE condition, or in a JOIN condition. You have to resolve such ambiguities by qualifying the non-unique column name, that is, by specifying the table that the column belongs to. You can do this using the full table name as a qualifier.

Qualifying a Column Name Using the Table Name

You can qualify the column name by adding the table name:

Code Snippet
12
SELECT Official.Name FROM Official;
NAME
Mr A
Mr B
Ms C
Ms D
Mr E
Mr F
Ms G
Ms H
Mr I

Having to repeat the full table name as a qualifier each time can be cumbersome. This is why you can use table aliases to introduce abbreviated table names and use the abbreviated form as a qualifier in the same SELECT statement.

Table Aliases

You can use table aliases in the projection list. Table aliases are defined in the FROM clause.

Code Snippet
12
SELECT o.Name, o.PNr FROM Official o;

You can use the (optional) keyword AS in the definition of a table aliases:

Code Snippet
12
SELECT o.Name, o.PNr FROM Official AS o;
NAMEPNR
Mr AP01
Mr BP02
Ms CP03
Ms DP04
Mr EP05
Mr FP06
Ms GP07
Ms HP08
Mr IP09

Supported Combinations of Qualified and Unqualified Column Names

If a table alias is defined in the FROM clause, you are not allowed to use the corresponding table name for qualification of a column name:

SQL queries showing supported combinations of qualified and unqualified column names.

Inner Join

An Inner Join is used to combine information from one table with corresponding information from another table, and to only include such rows in the result for which corresponding information is available.

Inner Join Explanation

One row of the left table and one row of the right table are always joined to a common result row, provided that the JOIN condition is fulfilled.

JOIN Condition: L.X = R.Y

Diagrams showing inner join.

Inner Join Implicit Syntax

One row of a table and one row of another table are always connected to a common result row provided that the JOIN condition is fulfilled.

The implicit JOIN condition is part of the WHERE clause.

The explicit JOIN condition is independent of the WHERE clause.

To whom is each car registered?

Code Snippet
123
SELECT * FROM Owner, Car WHERE OwnerID = Owner;
Code Snippet
12
SELECT * FROM Owner JOIN Car ON OwnerID = Owner;
OWNERIDNAMEBIRTHDAYCITYCARIDPLATENUMBERBRANDCOLORHPOWNER
H06Ms W1957-06-01WieslochF01HD-V 106Fiatred75H06
H03SAP AG?WalldorfF02HD-VW 4711VWblack120H03
H03SAP AG?WalldorfF03HD-JA 1972BMWblue184H03
H07IKEA?WalldorfF04HD-AL 1002Mercedeswhite136H07
H03SAP AG?WalldorfF05HD-MM 3206Mercedesblack170H03

Note

The following examples show the explicit syntax option only. Using the implicit syntax is more error-prone because the join condition cannot be distinguished from additional parts of a WHERE condition. This makes it easy to forget the join condition and produce a cross join by mistake.

Keyword INNER is Optional

Both JOIN and INNER JOIN are acceptable syntax variants.

The INNER JOIN is the most important JOIN variant (and therefore the default).

To whom is each car registered?

Code Snippet
12
SELECT * FROM Owner INNER JOIN Car ON OwnerID = Owner;
OWNERIDNAMEBIRTHDAYCITYCARIDPLATENUMBERBRANDCOLORHPOWNER
H06Ms W1957-06-01WieslochF01HD-V 106Fiatred75H06
H03SAP AG?WalldorfF02HD-VW 4711VWblack120H03
H03SAP AG?WalldorfF03HD-JA 1972BMWblue184H03
H07IKEA?WalldorfF04HD-AL 1002Mercedeswhite136H07
H03SAP AG?WalldorfF05HD-MM 3206Mercedesblack170H03

Joins Can be Combined with Projections

You can specify columns in the projection list of the JOIN.

To whom is each car registered?

Code Snippet
12
SELECT Name, Brand, Color FROM Owner JOIN Car ON OwnerID = Owner;
NAMEBRANDCOLOR
Ms WFiatred
SAP AGVWblack
SAP AGBMWblue
IKEAMercedeswhite
SAP AGMercedesblack
Mr VAudiyellow
SAP AGAudiblue
IKEAVWblack
Ms USkodared
HDM AGBMWblack
Ms UBMWgreen
HDM AGSkodared
IKEARenaultred
SAP AGMercedeswhite
SAP AGSkodablack
Ms YAudiorange
SAP AGRenaultred
Ms TVWblack

Table Aliases Can be Handy for Inner Joins

You can use table aliases in the projection list of the JOIN. The JOIN condition can also refer to table aliases. If column names are not unique, you must qualify them with the table aliases.

To whom is each car registered?

Code Snippet
12
SELECT o.Name, c.Brand, c.Color FROM Owner o JOIN Car c ON o.OwnerID = c.Owner;
NAMEBRANDCOLOR
Ms WFiatred
SAP AGVWblack
SAP AGBMWblue
IKEAMercedeswhite
SAP AGMercedesblack
Mr VAudiyellow
SAP AGAudiblue
IKEAVWblack
Ms USkodared
HDM AGBMWblack
Ms UBMWgreen
HDM AGSkodared
IKEARenaultred
SAP AGMercedeswhite
SAP AGSkodablack
Ms YAudiorange
SAP AGRenaultred
Ms TVWblack

Projections Can Reduce to One of the Tables Involved

You do not need to include a column from every involved table in the projection list. In addition to the JOIN condition you can specify a WHERE clause.

Who has a black car registered (at least one)?

Code Snippet
123
SELECT DISTINCT o.Name FROM Owner o JOIN Car c ON o.OwnerID = c.Owner WHERE c.Color = 'black';
NAME
Ms T
SAP AG
HDM AG
IKEA

The JOIN Condition Can be Complex

You can build the JOIN condition on multiple columns.

Who within the EU has a black car registered (at least one)?

Code Snippet
12345
SELECT DISTINCT o.Name AS "Owner's name" FROM Owner_EU o JOIN Car_EU c ON o.Country = c.Country AND o.OwnerID = c.Owner WHERE c.Color = 'black' ORDER BY o.Name;
Owner's name
HDM AG
IKEA
Ms O
Ms T
SAP AG
Señora R

Implicit INNER JOIN

You can join a table to itself. So-called self joins will require table aliases to be used.

Who is the manager of each employee?

Code Snippet
12
SELECT e.Name AS Employee, m.Name AS Manager FROM Official e JOIN Official m ON e.Manager = m.PNr;
EMPLOYEEMANAGER
Mr AMs D
Mr BMs D
Ms CMs D
Ms DMr I
Mr EMs H
Mr FMs H
Ms GMs H
Ms HMr I

Combining Two Tables

Combining more than two tables will require additional join conditions. To avoid cross joins, you must supply a valid join condition for each pairwise combination of tables in the join.

To whom is each stolen car registered?

Code Snippet
123
SELECT o.Name, c.Brand, c.Color, c.PlateNumber FROM Owner o JOIN Car c ON o.OwnerID = c.Owner JOIN Stolen s ON c.PlateNumber = s.PlateNumber;
NAMEBRANDCOLORPLATENUMBER
Ms WFiatredHD-V 106
Mr VAudiyellowHD-VW 1999
Ms YAudiorangeHD-Y 333

Use of Different Comparison Operators

You can use different comparison operators other than equality in the JOIN condition.

Which other owners is a given owner older than? (Note that this is not a very meaningful question.)

Code Snippet
12
SELECT o.Name AS "older", y.Name AS "younger" FROM Owner o JOIN Owner y ON o.Birthday < y.Birthday;
olderyounger
Ms TMs U
Ms TMr V
Ms TMs W
Ms TMr X
Ms TMs Y
Ms TMr Z
Ms UMr X
Ms UMs Y
Ms UMr Z
Mr VMs U
Mr VMs W
Mr VMr X
Mr VMs Y
Mr VMr Z
Ms WMs U
Ms WMr X
Ms WMs Y
Ms WMr Z
Ms YMr X
Mr ZMr X
Mr ZMs Y

Calculations and Functions in the JOIN Condition

You can use calculations and functions in the JOIN condition.

Which owners were born in the same year as other owner(s)?

Code Snippet
123
SELECT o1.Name, o1.Birthday, o2.Name, o2.Birthday FROM Owner o1 JOIN Owner o2 ON YEAR(o1.Birthday) = YEAR(o2.Birthday) AND o1.OwnerID < o2.OwnerID;
NAMEBIRTHDAYNAMEBIRTHDAY
Mr X1986-08-30Ms Y1986-02-10
Mr X1986-08-30Mr Z1986-02-03
Ms Y1986-02-10Mr Z1986-02-03

Outer Joins

The result set of an inner join does not contain the rows of any of the involved tables for which no corresponding row can be found in the other tables involved according to the join condition. Sometimes you may want to include such rows in the result set, to get the full set of rows of one table and augment the data with data from other tables as far as available. In addition to the inner join, three types of Outer Joins exist for this purpose:

  • Left outer join: includes all entries in the first (left) table, even if no corresponding entries are found in the second (right) table.

  • Right outer join: includes all entries in the second table even if no corresponding entries are found in the first table.

  • Full outer join: is the union of the left and right outer join.

In all three cases, the following factors apply:

  • A NULL value results for each column and row for which no corresponding data can be retrieved according to the join condition.

  • SAP HANA only supports the explicit syntax option for outer joins.

LEFT OUTER JOIN: Explanation

Left Outer Joins:

  • One row of a table and one row of another table are always connected to a common result row - provided the JOIN condition is fulfilled.
  • In addition, rows of the left table without matching row in the right table are copied to the query result. The missing values ​​(from the right table) are filled with NULL values.
Diagram showing Left Outer join.

LEFT OUTER JOIN: Example

Which car is registered to which individual or company? Individuals and companies that currently do not have any cars registered should also be included. Cars without a registration should not be included in the result.

Code Snippet
12
SELECT Name, CarID, Brand FROM Owner LEFT OUTER JOIN Car ON OwnerID = Owner;
NAMECARIDBRAND
Ms TF19VW
Ms UF09Skoda
Ms UF11BMW
SAP AGF02VW
SAP AGF03BMW
SAP AGF18Renault
SAP AGF05Mercedes
SAP AGF15Skoda
SAP AGF07Audi
SAP AGF14Mercedes
HDM AGF12Skoda
HDM AGF10BMW
Mr VF06Audi
Ms WF01Fiat
IKEAF13Renault
IKEAF08VW
IKEAF04Mercedes
Mr X??
Ms YF17Audi
Mr Z??

RIGHT OUTER JOIN: Explanation

Right Outer Joins:

  • One row of a table and one row of another table are always connected to a common result row, provided that the JOIN condition is fulfilled.
  • In addition, rows of the right table without matching row in the left table are copied to the query result. The missing values ​​(from the left table) are filled with NULL values.
  • Note that reversing the order of tables in the join condition AND switching the direction of the join ( LEFT ↔ RIGHT) produces the same result set.
Diagram showing Right Outer Join.

RIGHT OUTER JOIN: Example

Which car is registered to which individual or company? Cars without a current registration should also be included. Individuals and companies that currently do not have a car registered should not be included in the result.

Code Snippet
12
SELECT Name, CarID, Brand FROM Owner RIGHT OUTER JOIN Car ON OwnerID = Owner;
NAMECARIDBRAND
Ms WF01Fiat
SAP AGF02VW
SAP AGF03BMW
IKEAF04Mercedes
SAP AGF05Mercedes
Mr VF06Audi
SAP AGF07Audi
IKEAF08VW
Ms UF09Skoda
HDM AGF10BMW
Ms UF11BMW
HDM AGF12Skoda
IKEAF13Renault
SAP AGF14Mercedes
SAP AGF15Skoda
?F16Opel
Ms YF17Audi
SAP AGF18Renault
Ms TF19VW
?F20Audi

Full Outer Join

FULL OUTER JOIN: Explanation

One row of a table and one row of another table are always connected to a common result row, provided that the JOIN condition is fulfilled. In addition, rows of both tables without matching records are copied to the query result. The missing values ​​(from the other table) are filled with NULL values.

Diagram showing Full Outer join.

FULL OUTER JOIN: Example

Which car is registered to which individual or company? Individuals and companies that currently do not have a car registered should be included. Cars without a current registration should be included in the result.

Code Snippet
12
SELECT Name, CarID, Brand FROM Owner FULL OUTER JOIN Car ON OwnerID = Owner;
NAMECARIDBRAND
Ms WF01Fiat
SAP AGF02VW
SAP AGF03BMW
IKEAF04Mercedes
SAP AGF05Mercedes
Mr VF06Audi
SAP AGF07Audi
IKEAF08VW
Ms UF09Skoda
HDM AGF10BMW
Ms UF11BMW
HDM AGF12Skoda
IKEAF13Renault
SAP AGF14Mercedes
SAP AGF15Skoda
?F16Opel
Ms YF17Audi
SAP AGF18Renault
Ms TF19VW
?F20Audi
Mr X??
Mr Z??

Outer Self Joins

Each type of outer join supports joining a table with itself. The following shows an example of a left outer join operating on a single table.

  • As with inner self joins, table aliases must be used.
  • Who is the manager of which employee?
  • Employees without a manager should be included.
  • Only managers with employees should be included.
Code Snippet
12
SELECT e.Name AS Employee, m.Name AS Manager FROM Official e LEFT OUTER JOIN Official m ON e.Manager = m.PNr;
EMPLOYEEMANAGER
Mr AMs D
Mr BMs D
Ms CMs D
Ms DMr I
Mr EMs H
Mr FMs H
Ms GMs H
Ms HMr I
Mr I?

Replacing the keyword LEFT with RIGHT or FULL works in the example and leads to different result sets.

  • Using RIGHT OUTER JOIN would lead to a result including each official name in the MANAGER column, and only the names of the officials who have a manager assigned in the EMPLOYEE column.

  • USING FULL OUTER JOIN would lead to a result including each official name in the MANAGER column, and each official name in the EMPLOYEE column.

Similar to what is supported for cross joins and inner joins, you can also do the following with outer joins:

  • Use any comparison operator in the JOIN condition.

  • Join more than two tables, and join a table with itself.

  • Project the result set to a subset of columns. You do not have to include a column of every table involved in the projection list.

  • Rename columns.

  • Eliminate duplicates using DISTINCT.

  • Order the result set, use aggregate expressions, a GROUP BY clause, or a HAVING clause.

  • Use table aliases and reference them in the projection list and join condition. You have to qualify column names with the table names or use aliases if the column names are not unique.

Generally, any join may combine with any of the query operations already seen: column naming, results ordering, aggregates and grouped aggregates, functions and expressions, and so on. Query operations are independent and may be arbitrarily combined to produce as simple or complex a result as desired.