Skip to content

Commit 5e9f69d

Browse files
committed
Multi-joins and left joins
1 parent 0ff9a30 commit 5e9f69d

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

left_join.sql

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
-- Outline
2+
--
3+
-- So far, we've been talking about joins using the JOIN keyword. This is
4+
-- just one type of join, called an INNER JOIN. In fact, wherever we've
5+
-- been using the "JOIN" keyword we could instead replace it with "INNER JOIN"
6+
-- without changing anything.
7+
--
8+
-- There's a second type of join, called a left join or left outer join.
9+
-- It's a bit difficult to explain, but here are some blog posts:
10+
-- http://stackoverflow.com/questions/448023/what-is-the-difference-between-left-right-outer-and-inner-joins
11+
-- http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
12+
13+
-- Compare the output of these queries:
14+
-- JOIN
15+
SELECT employees.id, employees.first_name, employees.last_name,
16+
COUNT(DISTINCT(customers.id)) AS customers_served
17+
FROM employees
18+
JOIN customers
19+
ON (employees.id = customers.support_rep_id)
20+
GROUP BY employees.id;
21+
22+
-- LEFT JOIN
23+
SELECT employees.id, employees.first_name, employees.last_name,
24+
COUNT(DISTINCT(customers.id)) AS customers_served
25+
FROM employees
26+
LEFT JOIN customers
27+
ON (employees.id = customers.support_rep_id)
28+
GROUP BY employees.id;
29+
30+
-- Note: Unlike JOIN, with a LEFT JOIN it does matter which table comes first.
31+
-- That is,
32+
-- FROM TableA LEFT JOIN TableB
33+
-- **IS NOT THE SAME AS**
34+
-- FROM TableB LEFT JOIN TableA
35+
36+
-- In any join (inner, left, or anything else) there are three components:
37+
-- 1. The left table
38+
-- 2. The right table
39+
-- 3. The join condition
40+
-- An INNER JOIN returns only those rows from the left and right tables that
41+
-- match the join condition. A LEFT join returns all rows from the left table
42+
-- no matter what, and any rows from the right table that match the join condition.
43+
-- In other words, in an INNER JOIN, if a table in the left row doesn't have
44+
-- a corresponding row in the right table then that row (in the left table)
45+
-- won't be returned, whereas it WILL be returned in the result set using
46+
-- a LEFT JOIN.
47+
48+
-- You can see this in the COUNT queries above, but more clearly, here:
49+
-- This will return nothing since there are no customers who have Employee #1
50+
-- as a customer service rep. Remember, "INNER JOIN" is the same as "JOIN"
51+
SELECT *
52+
FROM employees
53+
INNER JOIN customers
54+
ON (employees.id = customers.support_rep_id)
55+
WHERE employees.id = 1;
56+
57+
-- This will return a SINGLE row, even though there are no corresponding customers.
58+
-- The fields from the customers table are displayed as empty (or NULL), telling
59+
-- us that Employee #1 has no associated customers.
60+
SELECT *
61+
FROM employees
62+
LEFT JOIN customers
63+
ON (employees.id = customers.support_rep_id)
64+
WHERE employees.id = 1;
65+
66+
-- Employees is the left table, customers is the right table, and the join
67+
-- condition is employees.id = customers.support_rep_id.
68+
69+
-- One handy thing is that this allows us to create queries like...
70+
-- Show me all employees who don't support any customers
71+
72+
SELECT *
73+
FROM employees
74+
LEFT JOIN customers
75+
ON (employees.id = customers.support_rep_id)
76+
WHERE customers.id IS NULL;
77+
78+
-- There are no exercises, here, because the toy database doesn't have
79+
-- interesting enough data to merit the use of LEFT JOINs in many contexts.
80+
-- For example, this query would return all customers who had yet to make an
81+
-- order. In the toy database, there are no such customers, alas!
82+
83+
SELECT *
84+
FROM customers
85+
LEFT JOIN invoices
86+
ON (invoices.customer_id = customers.id)
87+
WHERE invoices.id IS NULL;

multi_join.sql

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
-- Outline
2+
--
3+
-- All of these JOINs requires more than two tables.
4+
-- Remember: then using the JOIN keyword it doesn't matter what order we join
5+
-- the tables in. That is,
6+
--
7+
-- SELECT * FROM TableA JOIN TableB ON (TableA.id = TableB.table_a_id)
8+
--
9+
-- is the same as
10+
--
11+
-- SELECT * FROM TableB JOIN TableA ON (TableA.id = TableB.table_a_id)
12+
--
13+
-- Also remember: the syntax TableA.first_name means the "first_name" field
14+
-- from the table named TableA. Field names have to be unique in a given table.
15+
-- That is, you can't have two fields / columns named "first_name" in the same
16+
-- table.
17+
--
18+
-- However, two *different* tables can both have a "first_name" field. For
19+
-- example, you might have a "customers" table and an "employees" table, both
20+
-- of which have "first_name", "last_name", and "email" fields. If you have
21+
-- a query that involves *both* customers and employees, you'll need to refer
22+
-- to fields using their table name, i.e., customers.first_name,
23+
-- employees.first_name, customers.email, and so on.
24+
25+
-- Remember, the "skeleton" for a SELECT query with JOINs looks like
26+
--
27+
-- SELECT <field names>
28+
-- FROM <table1>
29+
-- JOIN <table2>
30+
-- ON (<join condition>)
31+
-- JOIN <table3>
32+
-- ON (<join condition>)
33+
-- WHERE <filtering clauses>
34+
-- GROUP BY / ORDER BY / LIMIT / etc.
35+
--
36+
-- This is the general order, but a SELECT query *always* needs a FROM clause.
37+
38+
-- Exercises
39+
--
40+
41+
-- What are the five highest grossing hip hop tracks?
42+
43+
-- What are the 3 least frequently-purchased tv shows?
44+
45+
-- What are the 5 highest-grossing genres?
46+
47+
-- Who are the 5 artists with the longest average track length?
48+
49+
-- Write a query that sorts a specific album's tracks by sales volume (you'll have to pick an arbitrary album title)
50+
-- e.g., "Give me the the tracks from Alanis Morissette's Jagged Little Pilled sorted by sales volume"
51+
52+
-- Write a query that sorts a specific album's tracks by gross sales (you'll have to pick an arbitrary album title)
53+
54+
-- How would you handle the case where two different artists have albums with the same name?
55+
-- e.g., sometimes both Peter Gabriel's first album and Led Zeppelin's first album are referred to as "One" or "I"
56+
57+
-- We're runnin' low on queries! Come up with 3-5 of your own and write them.

0 commit comments

Comments
 (0)