Outer Joins

In the joins discussed so far, only matching rows (rows with values in the specified columns that satisfy the join condition) are included in the results. In a sense, these join operations eliminate the information contained in the rows that do not match.

However, it is sometimes desirable to retain the nonmatching information by including nonmatching rows in the results of a join. To do this, you can use an outer join. Transact-SQL provides two outer join operators: *=, which includes all rows from the first-named table, and =*, which includes all rows from the second-named table.

Consider a join of the authors table and the publishers table on their city columns. The results show only the authors who live in cities where a publisher is located (in this case, Abraham Bennet and Cheryl Carson).

To include all authors in the results, regardless of whether a publisher is located in the same city, use an outer join. Here's what the query and results of the outer join look like:

SELECT au_fname, au_lname, pub_name
FROM authors, publishers
WHERE authors.city *= publishers.city
au_fname
au_lname
pub_name
-----------
--------------
--------------------
Johnson
White
(null)
Marjorie
Green
(null)
Cheryl
Carson
Algodata Infosystems
Michael
O'Leary
(null)
Dean
Straight
(null)
Meander
Smith
(null)
Abraham
Bennet
Algodata Infosystems
Ann
Dull
(null)
Burt
Gringlesby
(null)
Charlene
Locksley
(null)
Morningstar
Greene
(null)
Reginald
Blotchet-Halls
(null)
Akiko
Yokomoto
(null)
Innes
del Castillo
(null)
Michel
DeFrance
(null)
Dirk
Stringer
(null)
Stearns
MacFeather
(null)
Livia
Karsen
(null)
Sylvia
Panteley
(null)
Sheryl
Hunter
(null)
Heather
McBadden
(null)
Anne
Ringer
(null)
Albert
Ringer
(null)




(23 row(s) affected)

The *= operator distinguishes the outer join from an ordinary (equijoin) join. It tells SQL Server to include all rows in the authors table in the results, whether or not there is a match on the city column in the publishers table. Notice that in the results, there is no matching data for most of the authors listed, so these rows contain null values in the pub_name column.

Note Because bit columns do not permit null values, a value of 0 appears in an outer join when there is no match for a bit column in the inner table.

The other outer join operator, =*, indicates that all rows in the second table are to be included in the results, regardless of whether there is matching data in the first table:

SELECT au_fname, au_lname, pub_name
FROM authors, publishers
WHERE authors.city =* publishers.city

An outer join can be further restricted by comparing it to a constant. This means that you can zoom in on precisely the value or values you want to see, and use the outer join to list the rows that didn't make the cut. For example, to find out which title has sold more than 50 copies, use this query:

SELECT stor_id, qty, title
FROM sales, titles
WHERE qty > 50
    AND sales.title_id = titles.title_id
stor_id
title
-------
--------------------
7066
Is Anger the Enemy?



(1 row(s) affected)

To also show the titles that didn't sell more than 50 copies in any one store, use an outer join:

SELECT stor_id, qty, title
FROM sales, titles
WHERE qty > 50
    AND sales.title_id =* titles.title_id
stor_id
title
------- 
-----------------------------------------------------------
(null)
The Busy Executive's Database Guide
(null)
Cooking with Computers: Surreptitious Balance Sheets
(null)
You Can Combat Computer Stress!
(null)
Straight Talk About Computers
(null)
Silicon Valley Gastronomic Treats
(null)
The Gourmet Microwave
(null)
The Psychology of Computer Cooking
(null)
But Is It User Friendly?
(null)
Secrets of Silicon Valley
(null)
Net Etiquette
(null)
Computer Phobic and Non-Phobic Individuals: Behavior 
Variations
7066
Is Anger the Enemy?
(null)
Life Without Fear
(null)
Prolonged Data Deprivation: Four Case Studies
(null)
Emotional Security: A New Algorithm
(null)
Onions, Leeks, and Garlic: Cooking Secrets of the 
Mediterranean
(null)
Fifty Years in Buckingham Palace Kitchens
(null)
Sushi, Anyone?

(18 row(s) affected)



Outer Join Restrictions

Transact-SQL does not allow both nested outer joins and inner joins nested within an outer join. A table can, however, participate in an inner join and be the outer table in an outer join, as illustrated in this example:

SELECT royaltyper, au_lname, pub_name
FROM titleauthor, authors, publishers
WHERE titleauthor.au_id = authors.au_id
    AND authors.city *= publishers.city

The following shorthand can also be used to express the above example:

titleauthor = authors *= publishers

Generalizing and removing table names, this becomes:

T1 = T2 *= T3

Using this notation, the following illustration shows both legal and illegal combinations of inner and outer joins.

The following example is not valid because publishers cannot be the inner table in an outer join and still participate in an inner join:

SELECT title, au_lname, pub_name
FROM authors, publishers, titles
WHERE authors.city *= publishers.city
    AND publishers.pub_id = titles.pub_id

The qualification in the query does not restrict the number of rows returned; instead, it affects which rows contain null values. For rows that do not meet the qualification, NULL appears in the inner table's columns of those rows.