Full Outer Join in sqlite on 4 tables
-
05-07-2021 - |
Question
I need to join 4 tables based on a common primary key. If sqlite implemented full outer joins it might look something like this (with optimization not taken into account).
SELECT S.pair, C.ball, P.bluejeans, B.checkered
FROM Socks S
FULL OUTER JOIN Caps C
FULL OUTER JOIN Pants P
FULL OUTER JOIN Boxers B
WHERE S.color = C.color AND S.color = P.color AND S.color = B.color;
I've looked long and hard and the best I found was this 2 table sqlite full join implemented with left joins and union alls:
SELECT employee.*, department.*
FROM employee LEFT JOIN department
ON employee.DepartmentID = department.DepartmentID
UNION ALL SELECT employee.*, department.*
FROM department LEFT JOIN employee
ON employee.DepartmentID = department.DepartmentID
WHERE employee.DepartmentID IS NULL;
I'm trying to modify this to work for more than 2 tables but I'm new to SQL and I'm not getting too far. Is it possible to get this result in a reasonable amount of time?
I think I have a correct implementation for 3 tables (it might not be correct) but I still can't seem to get it for 4. Here's what I have for 3:
SELECT S.pair, C.ball, P.bluejeans
FROM Socks S LEFT JOIN Caps C LEFT JOIN Pants P
ON C.color = S.color AND P.color = S.color
UNION ALL
SELECT S.pair, C.ball, P.bluejeans
FROM Socks S LEFT JOIN Caps C LEFT JOIN Pants P
ON S.color = C.color AND S.color = P.color
WHERE S.color IS NULL;
Any help is much appreciated
Solution
The general construction for a full outer join between two tables A
and B
in SQLite indeed is:
SELECT ... FROM A LEFT JOIN B ON ...
UNION ALL
SELECT ... FROM B LEFT JOIN A ON ... WHERE A.key IS NULL
Now create a view SocksCaps
for the full outer join between Socks
and Caps
:
CREATE VIEW SocksCaps AS
SELECT ... FROM Socks LEFT JOIN Caps ON ...
UNION ALL
SELECT ... FROM Caps LEFT JOIN Socks ON ... WHERE Socks.color IS NULL
Do the same for Pants
and Boxers
.
Then treat these views just like tables and do a full outer join with the same construction:
SELECT ... FROM SocksCaps LEFT JOIN PantsBoxers ON ...
UNION ALL
SELECT ... FROM PantsBoxers LEFT JOIN SocksCaps ON ... WHERE SocksCaps.color IS NULL