|
| 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; |
0 commit comments