Brainlag
  1. Library
  2. Concepts
  3. SQL

JOIN: two tables into one result

A JOIN pairs rows from two tables wherever a column matches. INNER keeps only the pairs; LEFT keeps every row of the first table.

SQL10 min

Rows meet where the keys match

players has names. scores has points, with a player_id saying whose they are. JOIN ... ON players.id = scores.player_id walks through the pairs and keeps the ones where the two numbers are the same. Pick a result row to see which two rows made it. Then switch to LEFT JOIN and watch Dev appear.

How the JOIN pairs rows

players joined with scores on id = player_id.

Ana has two scores, so she appears twice. Dev has none, so INNER JOIN drops him. The score for player 5 has no player, so it is dropped too: a join only keeps rows that found a partner.

LEFT JOIN keeps the left side

LEFT JOIN keeps every row of the first table. Where there is no partner, the columns from the second table are NULL. That is how you find things that are missing: players who never played, songs nobody streamed, students with no marks.

SQL
SELECT p.name
FROM players p
LEFT JOIN scores s ON s.player_id = p.id
WHERE s.player_id IS NULL;

Run it: names next to points

Run it, then change one thing and run it again.

Tables players, scores
players 4 rows, 2 columns
idname
1Ana
2Ben
3Cleo
4Dev
scores 5 rows, 3 columns
player_idgamepoints
1Rocket Run820
3Rocket Run640
1Pixel Golf310
2Pixel Golf455
5Rocket Run990
query.sql to run
SELECT p.name, s.game, s.points
FROM players p
JOIN scores s ON s.player_id = p.id
ORDER BY s.points DESC;

Every player, played or not

The query below only lists players who have a score. Change it so every player appears once with their number of scores, including Dev with 0.

exercise_1.sql to run
SELECT p.name, COUNT(*) AS games
FROM players p
JOIN scores s ON s.player_id = p.id
GROUP BY p.id;

Code editor. Press Control or Command plus Enter to run the code. Tab indents; to move focus out of the editor, press Escape and then Tab.