Does anyone use Right Outer Joins?
It depends on what side of the join you put each table.
If you want to return all rows from the left table, even if there are no matches in the right table... you use left join.
If you want to return all rows from the right table, even if there are no matches in the left table, you use right join.
Interestingly enough, I rarely used right joins.
In SQL Server one edge case where I have found right joins useful is when used in conjunction with join hints.
The following queries have the same semantics but differ in which table is used as the build input for the hash table (it would be more efficient to build the hash table from the smaller input than the larger one which the right join syntax achieves)
SELECT #Large.X
FROM #Small
RIGHT HASH JOIN #Large ON #Small.X = #Large.X
WHERE #Small.X IS NULL
SELECT #Large.X
FROM #Large
LEFT HASH JOIN #Small ON #Small.X = #Large.X
WHERE #Small.X IS NULL
Aside from that (product specific) edge case there are other general examples where a RIGHT JOIN
may be useful.
Suppose that there are three tables for People, Pets, and Pet Accessories. People may optionally have pets and these pets may optionally have accessories
CREATE TABLE Persons
(
PersonName VARCHAR(10) PRIMARY KEY
);
INSERT INTO Persons
VALUES ('Alice'),
('Bob'),
('Charles');
CREATE TABLE Pets
(
PetName VARCHAR(10) PRIMARY KEY,
PersonName VARCHAR(10)
);
INSERT INTO Pets
VALUES ('Rover',
'Alice'),
('Lassie',
'Alice'),
('Fifi',
'Charles');
CREATE TABLE PetAccessories
(
AccessoryName VARCHAR(10) PRIMARY KEY,
PetName VARCHAR(10)
);
INSERT INTO PetAccessories
VALUES ('Ball', 'Rover'),
('Bone', 'Rover'),
('Mouse','Fifi');
If the requirement is to get a result listing all people irrespective of whether or not they own a pet and information about any pets they own that also have accessories.
This doesn't work (Excludes Bob)
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Persons P
LEFT JOIN Pets Pt
ON P.PersonName = Pt.PersonName
INNER JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName;
This doesn't work (Includes Lassie)
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Persons P
LEFT JOIN Pets Pt
ON P.PersonName = Pt.PersonName
LEFT JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName;
This does work (but the syntax is much less commonly understood as it requires two ON
clauses in succession to achieve the desired logical join order)
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Persons P
LEFT JOIN Pets Pt
INNER JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName
ON P.PersonName = Pt.PersonName;
All in all probably easiest to use a RIGHT JOIN
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Pets Pt
JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName
RIGHT JOIN Persons P
ON P.PersonName = Pt.PersonName;
Though if determined to avoid this another option would be to introduce a derived table that can be left joined to
SELECT P.PersonName,
T.PetName,
T.AccessoryName
FROM Persons P
LEFT JOIN (SELECT Pt.PetName,
Pa.AccessoryName,
Pt.PersonName
FROM Pets Pt
JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName) T
ON T.PersonName = P.PersonName;
SQL Fiddles: MySQL, PostgreSQL, SQL Server