Lesson 1 of 10

Joining two tables

Goal

Matching rows with INNER JOIN

01

Explanation

A well-designed database doesn't repeat the customer's name on every order. It stores the name once in the customers table, and each order carries only the customer's ID in its customer_id column.

JOIN then brings the two tables together at query time, like this: FROM orders JOIN customers ON customers.id = orders.customer_id.

A plain JOIN is an INNER JOIN, which keeps only the rows that have a match in both tables. That means a customer with no orders doesn't show up in the result at all, and we'll fix that in the next lesson.

02

Your task

Show the name and total of every order, sorted from the largest amount to the smallest.

Checks

5 checks
  1. Five rows, one per order
  2. Columns are name and total
  3. Sorted by order amount, largest first
  4. The largest order is Khalid's, at 300
  5. Fahd is left out because he has no orders
Tables in this lesson
CREATE TABLE customers (
  id   INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  city TEXT NOT NULL
);

CREATE TABLE orders (
  id          INTEGER PRIMARY KEY,
  customer_id INTEGER REFERENCES customers(id),
  total       INTEGER NOT NULL,
  placed_on   TEXT    NOT NULL
);

INSERT INTO customers (id, name, city) VALUES
  (1, 'Layan',  'Riyadh'),
  (2, 'Khalid', 'Jeddah'),
  (3, 'Reem',   'Dammam'),
  (4, 'Fahd',   'Riyadh');

INSERT INTO orders (customer_id, total, placed_on) VALUES
  (1, 120, '2026-09-01'),
  (1,  80, '2026-09-12'),
  (2, 300, '2026-09-03'),
  (3,  45, '2026-09-20'),
  (2,  60, '2026-09-25');
03

Hints

0/3
query.sql
OutputSQLite (sql.js)

Loading SQLite.

–/5

Checks start once the environment is ready.

5 checks listed under “Your task”.