lesson 18 Joins & sets · intermediate
Connect tables with JOIN
Connect rows from related tables using matching keys.
the idea
A JOIN combines rows from two tables whose key values match. Write the relationship in ON: orders.customer_id = customers.customer_id. An inner join keeps only rows that find a match, and each output row is one matched pair.
Dataset: Retail
The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.
customers4 columns · 848 rows
| customer_idnumber · unique id | countrytext | regiontext | first_order_atdate & time |
|---|---|---|---|
| 12347 | Iceland | Europe | 2010-10-31 14:20:00 |
| 12353 | Bahrain | Rest of World | 2010-10-27 12:44:00 |
| 12359 | Cyprus | Europe | 2009-12-05 13:32:00 |
| 12373 | Austria | Europe | 2010-02-04 12:08:00 |
| 12374 | Austria | Europe | 2010-04-30 14:01:00 |
| 12384 | Switzerland | Europe | 2011-08-10 11:23:00 |
- customer_idnumber · unique id
- 12347
- countrytext
- Iceland
- regiontext
- Europe
- first_order_atdate & time
- 2010-10-31 14:20:00
- customer_idnumber · unique id
- 12353
- countrytext
- Bahrain
- regiontext
- Rest of World
- first_order_atdate & time
- 2010-10-27 12:44:00
- customer_idnumber · unique id
- 12359
- countrytext
- Cyprus
- regiontext
- Europe
- first_order_atdate & time
- 2009-12-05 13:32:00
- customer_idnumber · unique id
- 12373
- countrytext
- Austria
- regiontext
- Europe
- first_order_atdate & time
- 2010-02-04 12:08:00
- customer_idnumber · unique id
- 12374
- countrytext
- Austria
- regiontext
- Europe
- first_order_atdate & time
- 2010-04-30 14:01:00
- customer_idnumber · unique id
- 12384
- countrytext
- Switzerland
- regiontext
- Europe
- first_order_atdate & time
- 2011-08-10 11:23:00
first 6 of 848 rows · your queries use all of them
orders6 columns · 6,722 rows
| order_idnumber · unique id | invoice_notext | customer_idnumber · links to customers | ordered_atdate & time | countrytext | order_typetext |
|---|---|---|---|---|---|
| 1 | 489438 | 18102 | 2009-12-01 09:24:00 | United Kingdom | sale |
| 2 | 489517 | 16329 | 2009-12-01 11:34:00 | United Kingdom | sale |
| 3 | C489528 | 16714 | 2009-12-01 11:50:00 | United Kingdom | cancellation |
| 4 | 489529 | 17984 | 2009-12-01 11:51:00 | United Kingdom | sale |
| 5 | 489532 | 13394 | 2009-12-01 11:58:00 | United Kingdom | sale |
| 6 | 489540 | 12913 | 2009-12-01 12:18:00 | United Kingdom | sale |
- order_idnumber · unique id
- 1
- invoice_notext
- 489438
- customer_idnumber · links to customers
- 18102
- ordered_atdate & time
- 2009-12-01 09:24:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 2
- invoice_notext
- 489517
- customer_idnumber · links to customers
- 16329
- ordered_atdate & time
- 2009-12-01 11:34:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 3
- invoice_notext
- C489528
- customer_idnumber · links to customers
- 16714
- ordered_atdate & time
- 2009-12-01 11:50:00
- countrytext
- United Kingdom
- order_typetext
- cancellation
- order_idnumber · unique id
- 4
- invoice_notext
- 489529
- customer_idnumber · links to customers
- 17984
- ordered_atdate & time
- 2009-12-01 11:51:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 5
- invoice_notext
- 489532
- customer_idnumber · links to customers
- 13394
- ordered_atdate & time
- 2009-12-01 11:58:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 6
- invoice_notext
- 489540
- customer_idnumber · links to customers
- 12913
- ordered_atdate & time
- 2009-12-01 12:18:00
- countrytext
- United Kingdom
- order_typetext
- sale
first 6 of 6,722 rows · your queries use all of them
products6 columns · 5,304 rows
| stock_codetext · unique id | descriptiontext | category_idnumber · links to categories | list_pricedecimal | first_sold_atdate & time | is_merchandisenumber |
|---|---|---|---|---|---|
| 10002 | INFLATABLE POLITICAL GLOBE | 17 | 0.85 | 2009-12-01 09:08:00 | 1 |
| 10002R | ROBOT PENCIL SHARPNER | 8 | 5.17 | 2009-12-02 14:43:00 | 1 |
| 10080 | GROOVY CACTUS INFLATABLE | 17 | 0.39 | 2009-12-02 16:02:00 | 1 |
| 10109 | BENDY COLOUR PENCILS | 8 | 0.42 | 2009-12-03 12:31:00 | 1 |
| 10120 | DOGGY RUBBER | 17 | 0.21 | 2009-12-01 16:17:00 | 1 |
| 10123C | HEARTS WRAPPING TAPE | 8 | 0.65 | 2009-12-01 14:28:00 | 1 |
- stock_codetext · unique id
- 10002
- descriptiontext
- INFLATABLE POLITICAL GLOBE
- category_idnumber · links to categories
- 17
- list_pricedecimal
- 0.85
- first_sold_atdate & time
- 2009-12-01 09:08:00
- is_merchandisenumber
- 1
- stock_codetext · unique id
- 10002R
- descriptiontext
- ROBOT PENCIL SHARPNER
- category_idnumber · links to categories
- 8
- list_pricedecimal
- 5.17
- first_sold_atdate & time
- 2009-12-02 14:43:00
- is_merchandisenumber
- 1
- stock_codetext · unique id
- 10080
- descriptiontext
- GROOVY CACTUS INFLATABLE
- category_idnumber · links to categories
- 17
- list_pricedecimal
- 0.39
- first_sold_atdate & time
- 2009-12-02 16:02:00
- is_merchandisenumber
- 1
- stock_codetext · unique id
- 10109
- descriptiontext
- BENDY COLOUR PENCILS
- category_idnumber · links to categories
- 8
- list_pricedecimal
- 0.42
- first_sold_atdate & time
- 2009-12-03 12:31:00
- is_merchandisenumber
- 1
- stock_codetext · unique id
- 10120
- descriptiontext
- DOGGY RUBBER
- category_idnumber · links to categories
- 17
- list_pricedecimal
- 0.21
- first_sold_atdate & time
- 2009-12-01 16:17:00
- is_merchandisenumber
- 1
- stock_codetext · unique id
- 10123C
- descriptiontext
- HEARTS WRAPPING TAPE
- category_idnumber · links to categories
- 8
- list_pricedecimal
- 0.65
- first_sold_atdate & time
- 2009-12-01 14:28:00
- is_merchandisenumber
- 1
first 6 of 5,304 rows · your queries use all of them
order_items7 columns · 125,613 rows
| order_item_idnumber · unique id | order_idnumber · links to orders | line_numbernumber | stock_codetext · links to products | descriptiontext | quantitynumber | unit_pricedecimal |
|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 21329 | DINOSAURS WRITING SET | 28 | 0.98 |
| 2 | 1 | 2 | 21252 | SET OF MEADOW FLOWER STICKERS | 30 | 1.69 |
| 3 | 1 | 3 | 21100 | CHARLIE AND LOLA CHARLOTTE BAG | 30 | 1.15 |
| 4 | 1 | 4 | 21033 | JUMBO BAG CHARLIE AND LOLA TOYS | 30 | 2 |
| 5 | 1 | 5 | 20711 | JUMBO BAG TOYS | 60 | 1.3 |
| 6 | 1 | 6 | 21410 | COUNTRY COTTAGE DOORSTOP GREEN | 32 | 2.5 |
- order_item_idnumber · unique id
- 1
- order_idnumber · links to orders
- 1
- line_numbernumber
- 1
- stock_codetext · links to products
- 21329
- descriptiontext
- DINOSAURS WRITING SET
- quantitynumber
- 28
- unit_pricedecimal
- 0.98
- order_item_idnumber · unique id
- 2
- order_idnumber · links to orders
- 1
- line_numbernumber
- 2
- stock_codetext · links to products
- 21252
- descriptiontext
- SET OF MEADOW FLOWER STICKERS
- quantitynumber
- 30
- unit_pricedecimal
- 1.69
- order_item_idnumber · unique id
- 3
- order_idnumber · links to orders
- 1
- line_numbernumber
- 3
- stock_codetext · links to products
- 21100
- descriptiontext
- CHARLIE AND LOLA CHARLOTTE BAG
- quantitynumber
- 30
- unit_pricedecimal
- 1.15
- order_item_idnumber · unique id
- 4
- order_idnumber · links to orders
- 1
- line_numbernumber
- 4
- stock_codetext · links to products
- 21033
- descriptiontext
- JUMBO BAG CHARLIE AND LOLA TOYS
- quantitynumber
- 30
- unit_pricedecimal
- 2
- order_item_idnumber · unique id
- 5
- order_idnumber · links to orders
- 1
- line_numbernumber
- 5
- stock_codetext · links to products
- 20711
- descriptiontext
- JUMBO BAG TOYS
- quantitynumber
- 60
- unit_pricedecimal
- 1.3
- order_item_idnumber · unique id
- 6
- order_idnumber · links to orders
- 1
- line_numbernumber
- 6
- stock_codetext · links to products
- 21410
- descriptiontext
- COUNTRY COTTAGE DOORSTOP GREEN
- quantitynumber
- 32
- unit_pricedecimal
- 2.5
first 6 of 125,613 rows · your queries use all of them
worked example
Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.
See customer_id on each order. Run this. customer_id on orders matches customers.customer_id on the other table.
step-1.sqlSELECT order_id, customer_id FROM orders WHERE ordered_at >= '2011-12-09' LIMIT 10;
Join orders to customers. Run this. JOIN attaches each order to its customer row so you can read region.the pattern
example.sqlSELECT o.order_id, o.invoice_no, c.region FROM orders o JOIN customers c ON c.customer_id = o.customer_id WHERE o.ordered_at >= '2011-12-09';
common mistake
Anonymous orders have customer_id NULL, so an inner join to customers silently drops them. That is correct only if the question is about identified customers.