SQL Joins

You Are Here

Foreign Key

Database tables have references to other tables.

user

blog_post

User Id

Foreign Key

user

blog_post

user_id

CREATE TABLE user (
    user_id bigserial primary key,
    username text NOT NULL
);
CREATE TABLE blog_post (
    blog_post_id bigserial primary key,
    user_id bigserial references user(user_id),
    post_text text
);
  • One table "points" to another table using a foreign key
  • In our case, each `blog_post` points to exactly one `user`

Foreign Key

user

blog_post

user_id

1; teb-a-licious

2; liz-a-tronic

3; cho-a-ramic

1; 1; "blogs rule"

2; 1; "blogs are fine"

3; 3; "I like blogging"

4; 2; "blogs are divine"

Use FKs to tell who wrote what!

Foreign Key

user

blog_post

user_id

1; teb-a-licious

2; liz-a-tronic

3; cho-a-ramic

1;  1;   "blogs rule"

2;  1;   "blogs are fine"

3;  3;   "I like blogging"

4;  2;   "blogs are divine"

CREATE TABLE user (
    user_id bigserial primary key,
    username text NOT NULL
);
CREATE TABLE blog_post (
    blog_post_id bigserial primary key,
    user_id bigserial references user(user_id),
    post_text text
);

Joins

  • Joins require two tables.

  • The result is a temporary table.

  • This table has data from both input tables.

  • Joins use an "on" clause to define the relationship between the tables.

  • To join user and blog_post with the shared user_id:

select * from user 
join blog_post on user.user_id=blog_post.user_id;

Simple Join

result: "temporary table"

teb-a-licious

teb-a-licious

liz-a-tronic

cho-a-ramic

"blogs rule"

"blogs are fine"

"blogs are divine"

"I like blogging"

select 
  u.username,
  bp.post_text
from user u
join blog_post bp on u.user_id=bp.user_id;

Chain Joins

In SQL you can chain joins together as much as you'd like

user

blog_post

user_id

comment

blog_post_id

Chain Joins

Lets say we want all the comments on a blog post as well as the original author and the original blog_text.

 

select 
  blog_author.username as author,
  bp.post_text as post_text,
  comment.comment_text as comment_content,
from user blog_author
join blog_post bp on u.user_id=bp.user_id
join comment comment on c.blog_post_id=bp.blog_post_id;
author post_text comment_text

user

blog_post

user_id

comment

user_id

blog_post_id

Chain Joins

Lets attach comments to users

Chain Joins

Lets add the comment author to our join.

Notice that we're joining the user table twice now, with different aliases.

select 
  blog_author.username as author,
  bp.post_text as post_text,
  comment.comment_text as comment_content,
  commenter.username as comment_auth
from user blog_author
join blog_post bp on u.user_id=bp.user_id
join comment comment on c.blog_post_id=bp.blog_post_id
join user commenter on commenter.user_id=comment.user_id;
author post_text comment_text comment_auth

Join Types

Set Theory in Venn Diagrams

You Are Here

Join Types

Remember, you're always joining exactly 2 tables

id name       id  name
-- ----       --  ----
1  Pirate     1   Rutabaga
2  Monkey     2   Pirate
3  Ninja      3   Darth Vader
4  Spaghetti  4   Ninja

Lets use this sample dataset to explore join types

(http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/)

Join Types

There are 4 main join types

Inner

Full Outer

Left

Right

Inner Join

Inner joins target records where both tables match. Inner joins do not result in nulls since they require a match by definition.

SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name
id  name       id   name
--  ----       --   ----
1   Pirate     2    Pirate
3   Ninja      4    Ninja

Full Outer Join

Full Outer Joins target ALL records from BOTH tables. Nulls appear when either side has an unmatched record.

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
id    name       id    name
--    ----       --    ----
1     Pirate     2     Pirate
2     Monkey     null  null
3     Ninja      4     Ninja
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

Full Outer Join+

We can target the opposite of an inner join using a where clause

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null
id    name       id    name
--    ----       --    ----
2     Monkey     null  null
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

Left Outer Join

Left Outer Joins target records from the first table and then attach the data from the second table. Nulls appear when there isn't a match on the right hand table

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

Left Outer Join+

If we add a where clause, we can select only results which don't have a right hand side match for our temporary table

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
where TableB.id IS null
id  name       id    name
--  ----       --    ----
2   Monkey     null  null
4   Spaghetti  null  null

Right Joins use the second table as their starting point

Copy of Database Joins

By momolove

Copy of Database Joins

  • 1,052