INNER JOIN
Show each loan with the title or the member it belongs to.
JOIN another table ON the column the two share, like a lookup.
For every loan, show the name of the member who borrowed it and the loan_date.
Run your query to see the result table.
Press the green Run button or Ctrl+Enter.
How JOIN, ON works
JOIN (INNER) keeps only the rows that match in both tables.
members
| member_id | name |
|---|---|
| 101 | Ava |
| 102 | Ben |
| 103 | Cara |
| 104 | Dev |
loans
| loan_id | member_id | loan_date |
|---|---|---|
| 1 | 101 | 2026-01-12 |
| 2 | 103 | 2026-02-03 |
| 3 | 101 | 2026-03-20 |
| 4 | 102 | 2026-04-08 |
| 5 | 105(deleted) | 2026-05-14 |
query
SELECT members.name, loans.loan_date FROM members JOIN loans ON members.member_id = loans.member_id;
result: 4 rows
| name | loan_date |
|---|---|
| Ava | 2026-01-12 |
| Ava | 2026-03-20 |
| Ben | 2026-04-08 |
| Cara | 2026-02-03 |
Keeps only rows that match in both tables. Dev (no loans) and loan 5 (no member) are left out.
Why is the data in two tables?
So each fact is stored once. A loan only holds the book's id; the title lives in
books. Change a title once and every loan shows the new one.What does
JOINdo?FROM loans JOIN books ON loans.book_id = books.book_idIt pairs each loan with the book whose id matches, so one row has columns from both tables.
Why write loans.book_id?
Both tables have a
book_id. Writing the table name first says which one you mean. Without it, SQL says the name is ambiguous.What happens to rows with no match?
JOIN(also writtenINNER JOIN) keeps only rows that match in both tables. A book nobody has borrowed is left out. The next lesson keeps them.How is this like Excel?
It's
XLOOKUPfor every row at once: look up each loan's book_id in the books table and bring back the title.
How other databases do it
The lessons run on SQLite. Most of SQL is the same everywhere; these are the places where this lesson's SQL differs.
| Database | How | Note |
|---|---|---|
| SQLite (these lessons) | FROM loans, books WHERE loans.book_id = books.book_id | Works everywhere, but JOIN ... ON keeps the link apart from the filters. |
| PostgreSQL | FROM loans, books WHERE ... | Works. JOIN ... ON is the usual style. |
| MySQL / MariaDB | FROM loans, books WHERE ... | Works. JOIN ... ON is the usual style. |
| SQL Server | FROM loans, books WHERE ... | Works. JOIN ... ON is the usual style. |
| Oracle | FROM loans, books WHERE ... | Common in older Oracle code; JOIN ... ON works since Oracle 9i. |
| Sybase ASE | FROM loans, books WHERE ... | Common in older Sybase code; JOIN ... ON works since ASE 12. |
Know someone fighting with a spreadsheet? Send them this page.