Deeper Dive into Foreign Keys and JOINs in SQL

This article will explore foreign keys in more detail and how to use "joins" to work with data across multiple tables.

Joins are crucial because they allow us to work with normalized data efficiently. Remember when we talked about organizing data effectively? We mentioned principles like avoiding repetition and using separate tables for different data types. Joins are the tool that allows us to bring this separated data back together when we need it.

For example, if we want to display a list of books with their authors and prices on our online bookstore's website, we can use a JOIN to get all this information in a single query, even though it's stored in separate tables.

Revisiting Foreign Keys

As we discussed earlier, a foreign key is a column in one table that refers to the primary key in another table. This creates a relationship between the two tables. Let's expand on this concept with a practical example.

Imagine we're building a database for a small online bookstore. We might have two main tables: Authors and Books. Here's how we could define these tables:

CREATE TABLE Authors (
    AuthorID INT PRIMARY KEY,
    Name VARCHAR(100)
);

CREATE TABLE Books (
    BookID INT PRIMARY KEY,
    Title VARCHAR(200),
    AuthorID INT,
    Price DECIMAL(10, 2),
    FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID)
);

In this example, AuthorID in the Books table is a foreign key that references the AuthorID in the Authors table. This relationship allows us to connect each book to its author without repeating the author's information for every book.

Let's add some data to these tables:

INSERT INTO Authors (AuthorID, Name) VALUES 
(1, 'J.K. Rowling'),
(2, 'George Orwell'),
(3, 'Jane Austen');

INSERT INTO Books (BookID, Title, AuthorID, Price) VALUES
(1, 'Harry Potter and the Philosopher''s Stone', 1, 20.99),
(2, '1984', 2, 15.99),
(3, 'Pride and Prejudice', 3, 12.99),
(4, 'Animal Farm', 2, 11.99);

Now that we have our data organized across two tables, how do we work with it? This is where JOINs come in.

Understanding JOINs

JOINs allow us to combine rows from two or more tables based on a related column between them. There are several types of JOINs, but we'll focus on the four main types: INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL OUTER JOIN.

INNER JOIN

An INNER JOIN returns only the rows where there's a match in both tables. It's like finding the intersection between two sets.

SELECT Books.Title, Authors.Name
FROM Books
INNER JOIN Authors ON Books.AuthorID = Authors.AuthorID;

This query will return:

Title                                       | Name
--------------------------------------------|--------------
Harry Potter and the Philosopher's Stone    | J.K. Rowling
1984                                        | George Orwell
Pride and Prejudice                         | Jane Austen
Animal Farm                                 | George Orwell

Here, we get all books along with their authors' names. If we had an author with no books or a book with no author in our database, they wouldn't appear in this result.

LEFT JOIN

A LEFT JOIN returns all rows from the left table (the first table mentioned in the query) and the matched rows from the right table. If there's no match, the result is NULL for columns from the right table.

SELECT Authors.Name, Books.Title
FROM Authors
LEFT JOIN Books ON Authors.AuthorID = Books.AuthorID;

If we had an author who hasn't written any books in our database, they would still appear in this result, but with NULL for the book title.

RIGHT JOIN

A RIGHT JOIN is the opposite of a LEFT JOIN. It returns all rows from the right table and the matched rows from the left table.

SELECT Books.Title, Authors.Name
FROM Authors
RIGHT JOIN Books ON Authors.AuthorID = Books.AuthorID;

This would show all books, even if they don't have an author in our Authors table (which isn't the case in our current data but could happen if we allowed books without known authors).

FULL OUTER JOIN

A FULL OUTER JOIN returns all rows when there's a match in either the left or right table.

SELECT Authors.Name, Books.Title
FROM Authors
FULL OUTER JOIN Books ON Authors.AuthorID = Books.AuthorID;

This would show all authors and all books, matching them where possible. If we had authors without books or books without authors, they would still appear in this result.

Practice Exercise

To solidify your understanding, try writing queries to answer these questions:

  1. How many books has each author written? (Hint: Use LEFT JOIN and COUNT)
  2. What is the average price of books for each author? (Hint: Use LEFT JOIN and AVG)
  3. List all authors, even if they haven't written any books in our database. Show the title as "No books" if the author hasn't written any. (Hint: Use LEFT JOIN and COALESCE)

Remember, practice is critical to mastering these concepts. Our next article will explore more advanced querying techniques based on these JOIN operations.

BeginnerDatabasePostgresqlSql
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.