More Join Types

Before we look at other join types, let's take note of something interesting about inner joins.

We know we have 2 users with names manuel_torp and ryley.denesik98

SELECT
  username,
  email
FROM tweeters
WHERE username IN (
  'manuel_torp',
  'ryley.denesik98'
);
username
VARCHAR
email
VARCHAR
manuel_torp
manuel79@gmail.com
ryley.denesik98
ryley36@gmail.com

But look what happens when we JOIN their information with their tweets from the tweets table…

SELECT
  tweeters.email,
  tweeters.username,
  tweets.body,
  tweets.created_at
FROM tweeters
INNER JOIN tweets
  ON tweeters.id = tweets.user_id
WHERE tweeters.username IN (
  'manuel_torp',
  'ryley.denesik98'
);
email
VARCHAR
username
VARCHAR
body
TEXT
created_at
TIMESTAMPTZ
manuel79@gmail.com
manuel_torp
Use the back-end PNG port, then you can index the cross-platform port!
2018-02-21 07:24:38.871+00
manuel79@gmail.com
manuel_torp
The COM program is down, synthesize the optical alarm so we can calculate the ADP bus!
2018-05-30 20:35:11.712+00

Notice that the user ryley.denesik98 doesn't appear in any of the rows. Why not? This is because ryley.denesik98 doesn't have any tweets.

The INNER JOIN will only keep rows in either table that have matching values for the join condition. Rows without any matching rows from the other table are removed. Sometimes that is exactly what you want. For example, if you are displaying a list of tweets and you don't need to show anything for users who haven't tweeted. However, you might want to make a page that shows some user information (maybe their email or profile picture) plus their tweets, and you might want to keep user information even if they haven't tweeted.

LEFT, RIGHT JOIN

If we want rows for users even if they have no tweets, we can use a LEFT JOIN in this situation.

SELECT
  tweeters.email,
  tweeters.username,
  tweets.body,
  tweets.created_at
FROM tweeters
LEFT JOIN tweets
  ON tweeters.id = tweets.user_id
WHERE tweeters.username IN (
  'manuel_torp',
  'ryley.denesik98'
);
email
VARCHAR
username
VARCHAR
body
TEXT
created_at
TIMESTAMPTZ
manuel79@gmail.com
manuel_torp
Use the back-end PNG port, then you can index the cross-platform port!
2018-02-21 07:24:38.871+00
manuel79@gmail.com
manuel_torp
The COM program is down, synthesize the optical alarm so we can calculate the ADP bus!
2018-05-30 20:35:11.712+00
ryley36@gmail.com
ryley.denesik98
NULLNULL

What's different now? The user ryley.denesik98 is there, and the tweet information is all NULL because they have no tweets. It's called a LEFT JOIN because the rows from the table on the "left side of the join" are preserved even if they have no matches for the join condition, and NULLs are filled instead. The "left" and "right" are determined by the order they appear in the query, i.e. FROM table_a JOIN table_b ON … means table_a is on the left and table_b is on the right.

This is often depicted with venn diagrams, like so:

INNER JOIN
LEFT JOIN

In these diagrams, the overlapping region in the middle represents the set of rows which do have matches for the join condition. The filled-in regions are the ones kept in the result, and the blank ones are filtered out.

Conceptually, the RIGHT JOIN is exactly the same as the LEFT JOIN, except that only rows from the right-hand table are kept if they have no match for the join condition.

Notice here that I switch the order of tweeters and tweets.

SELECT
  tweeters.email,
  tweeters.username,
  tweets.body,
  tweets.created_at
FROM tweets
RIGHT JOIN tweeters
  ON tweeters.id = tweets.user_id
WHERE tweeters.username IN (
  'manuel_torp',
  'ryley.denesik98'
);
email
VARCHAR
username
VARCHAR
body
TEXT
created_at
TIMESTAMPTZ
manuel79@gmail.com
manuel_torp
Use the back-end PNG port, then you can index the cross-platform port!
2018-02-21 07:24:38.871+00
manuel79@gmail.com
manuel_torp
The COM program is down, synthesize the optical alarm so we can calculate the ADP bus!
2018-05-30 20:35:11.712+00
ryley36@gmail.com
ryley.denesik98
NULLNULL
RIGHT JOIN

FULL JOIN

Once you understand the LEFT and RIGHT JOIN, the FULL JOIN, a.k.a FULL OUTER JOIN (same thing), is easy to understand. A FULL JOIN will match up rows which have a match, keep the rows from both tables if they have no match, and fill in NULL for either side when needed.

FULL (OUTER) JOIN

© 2022 Andrew Carlson. All rights reserved.