|
1 | 1 | ---
|
2 | 2 | Title: 'LEFT JOIN'
|
3 |
| -Description: 'Combines matching rows with rows from the left-side table.' |
| 3 | +Description: 'Combines rows from two or more tables based on a related column, returning all records from the left table and matching records from the right table.' |
4 | 4 | Subjects:
|
| 5 | + - 'Computer Science' |
5 | 6 | - 'Data Science'
|
6 | 7 | Tags:
|
7 | 8 | - 'Database'
|
8 |
| - - 'Queries' |
9 | 9 | - 'Join'
|
10 |
| - - 'PostgreSQL' |
11 |
| - - 'MySQL' |
12 |
| - - 'SQLite' |
| 10 | + - 'Queries' |
| 11 | + - 'SQL' |
13 | 12 | - 'Tables'
|
14 | 13 | CatalogContent:
|
15 | 14 | - 'learn-sql'
|
16 | 15 | - 'paths/analyze-data-with-sql'
|
17 |
| - - 'paths/design-databases-with-postgresql' |
18 | 16 | ---
|
19 | 17 |
|
20 |
| -The **`LEFT JOIN`** command combines matching rows with rows from the left-side table. |
| 18 | +The **`LEFT JOIN`** is a fundamental SQL operation that combines rows from two or more tables based on a related column between them. It retrieves all records from the left table and only the matching records from the right table. When there is no matching record in the right table, `NULL` values are returned for the columns from the right table, ensuring that no data from the left table is lost in the result set. |
| 19 | + |
| 20 | +The GIF here showcases the behaviour of a `LEFT JOIN`: |
21 | 21 |
|
22 | 22 | 
|
23 | 23 |
|
| 24 | +`LEFT JOIN` is particularly valuable in scenarios where all records from a primary table need to be preserved while optionally including related information from secondary tables. Common use cases include generating reports with optional data, displaying user profiles with optional contact information, analyzing sales data with optional customer details, and creating comprehensive datasets where missing relationships should not exclude primary records. |
| 25 | + |
24 | 26 | ## Syntax
|
25 | 27 |
|
26 |
| -```pseudo |
| 28 | +```sql |
27 | 29 | SELECT column_name(s)
|
28 |
| -FROM table_1 |
29 |
| -LEFT JOIN table_2 |
30 |
| - ON table_1.column_name = table_2.column_name; |
| 30 | +FROM table1 |
| 31 | +LEFT JOIN table2 ON table1.column_name = table2.column_name; |
| 32 | +``` |
| 33 | + |
| 34 | +**Syntax explanation:** |
| 35 | + |
| 36 | +- `SELECT column_name(s)`: Specifies the columns to retrieve from the joined tables |
| 37 | +- `FROM table1`: The left table, which serves as the primary source of data |
| 38 | +- `LEFT JOIN table2`: The right table to be joined with the left table |
| 39 | +- `ON table1.column_name = table2.column_name`: The join condition that specifies how the tables are related |
| 40 | + |
| 41 | +**Return value:** |
| 42 | + |
| 43 | +The `LEFT JOIN` returns a result set that includes all rows from the left table, with matching data from the right table where available, and `NULL` values for right table columns where no match exists. |
| 44 | + |
| 45 | +## Example 1: Basic `LEFT JOIN` Example |
| 46 | + |
| 47 | +This example demonstrates the fundamental usage of `LEFT JOIN` with customer and order data to show all customers regardless of whether they have placed orders: |
| 48 | + |
| 49 | +```sql |
| 50 | +-- Create customers table |
| 51 | +CREATE TABLE customers ( |
| 52 | + customer_id INT PRIMARY KEY, |
| 53 | + customer_name VARCHAR(50), |
| 54 | + city VARCHAR(50) |
| 55 | +); |
| 56 | + |
| 57 | +-- Insert sample data |
| 58 | +INSERT INTO customers (customer_id, customer_name, city) VALUES |
| 59 | +(1, 'Alice Johnson', 'New York'), |
| 60 | +(2, 'Bob Smith', 'Los Angeles'), |
| 61 | +(3, 'Carol Brown', 'Chicago'), |
| 62 | +(4, 'David Wilson', 'Houston'); |
| 63 | + |
| 64 | +-- Create orders table |
| 65 | +CREATE TABLE orders ( |
| 66 | + order_id INT PRIMARY KEY, |
| 67 | + customer_id INT, |
| 68 | + order_date DATE, |
| 69 | + total_amount DECIMAL(10, 2) |
| 70 | +); |
| 71 | + |
| 72 | +-- Insert sample data |
| 73 | +INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES |
| 74 | +(101, 1, '2024-01-15', 250.00), |
| 75 | +(102, 2, '2024-01-20', 150.00), |
| 76 | +(103, 1, '2024-02-01', 300.00); |
| 77 | + |
| 78 | +-- LEFT JOIN query to show all customers with their orders |
| 79 | +SELECT |
| 80 | + c.customer_id, |
| 81 | + c.customer_name, |
| 82 | + c.city, |
| 83 | + o.order_id, |
| 84 | + o.order_date, |
| 85 | + o.total_amount |
| 86 | +FROM customers c |
| 87 | +LEFT JOIN orders o ON c.customer_id = o.customer_id |
| 88 | +ORDER BY c.customer_id; |
| 89 | +``` |
| 90 | + |
| 91 | +The output produced by this code is: |
| 92 | + |
| 93 | +```shell |
| 94 | +| customer_id | customer_name | city | order_id | order_date | total_amount | |
| 95 | +|-------------|----------------|-------------|----------|------------|---------------| |
| 96 | +| 1 | Alice Johnson | New York | 101 | 2024-01-15 | 250.00 | |
| 97 | +| 1 | Alice Johnson | New York | 103 | 2024-02-01 | 300.00 | |
| 98 | +| 2 | Bob Smith | Los Angeles | 102 | 2024-01-20 | 150.00 | |
| 99 | +| 3 | Carol Brown | Chicago | NULL | NULL | NULL | |
| 100 | +| 4 | David Wilson | Houston | NULL | NULL | NULL | |
| 101 | +``` |
| 102 | + |
| 103 | +This query returns all customers from the customers table, along with their order information where available. Customer "David Wilson" appears in the results with `NULL` values for order details since he has not placed any orders, demonstrating how `LEFT JOIN` preserves all records from the left table. |
| 104 | + |
| 105 | +## Example 2: Employee Department Analysis |
| 106 | + |
| 107 | +This example shows how `LEFT JOIN` can be used to analyze employee distribution across departments, including employees who may not be assigned to any department: |
| 108 | + |
| 109 | +```sql |
| 110 | +-- Create departments table |
| 111 | +CREATE TABLE departments ( |
| 112 | + dept_id INT PRIMARY KEY, |
| 113 | + dept_name VARCHAR(50), |
| 114 | + location VARCHAR(50) |
| 115 | +); |
| 116 | + |
| 117 | +-- Insert department data |
| 118 | +INSERT INTO departments (dept_id, dept_name, location) VALUES |
| 119 | +(10, 'Sales', 'New York'), |
| 120 | +(20, 'Marketing', 'Chicago'), |
| 121 | +(30, 'Engineering', 'San Francisco'), |
| 122 | +(40, 'HR', 'Boston'); |
| 123 | + |
| 124 | +-- Create employees table |
| 125 | +CREATE TABLE employees ( |
| 126 | + emp_id INT PRIMARY KEY, |
| 127 | + emp_name VARCHAR(50), |
| 128 | + dept_id INT, |
| 129 | + salary DECIMAL(10, 2) |
| 130 | +); |
| 131 | + |
| 132 | +-- Insert employee data |
| 133 | +INSERT INTO employees (emp_id, emp_name, dept_id, salary) VALUES |
| 134 | +(1, 'John Doe', 10, 55000.00), |
| 135 | +(2, 'Jane Smith', 20, 62000.00), |
| 136 | +(3, 'Mike Johnson', 10, 48000.00), |
| 137 | +(4, 'Sarah Wilson', 30, 75000.00), |
| 138 | +(5, 'Tom Brown', NULL, 45000.00); -- Employee without department assignment |
| 139 | + |
| 140 | +-- LEFT JOIN to show all employees with their department information |
| 141 | +SELECT |
| 142 | + e.emp_id, |
| 143 | + e.emp_name, |
| 144 | + e.salary, |
| 145 | + d.dept_name, |
| 146 | + d.location |
| 147 | +FROM employees e |
| 148 | +LEFT JOIN departments d ON e.dept_id = d.dept_id |
| 149 | +ORDER BY e.emp_name; |
| 150 | +``` |
| 151 | + |
| 152 | +The output of this code will be: |
| 153 | + |
| 154 | +```shell |
| 155 | +| emp_id | emp_name | salary | dept_name | location | |
| 156 | +|--------|--------------|----------|-------------|----------------| |
| 157 | +| 2 | Jane Smith | 62000.00 | Marketing | Chicago | |
| 158 | +| 1 | John Doe | 55000.00 | Sales | New York | |
| 159 | +| 3 | Mike Johnson | 48000.00 | Sales | New York | |
| 160 | +| 4 | Sarah Wilson | 75000.00 | Engineering | San Francisco | |
| 161 | +| 5 | Tom Brown | 45000.00 | NULL | NULL | |
31 | 162 | ```
|
32 | 163 |
|
33 |
| -Every row in the left table is returned in the result set. If the join condition is not met, then `NULL` values are used to fill in the columns from the right table. |
| 164 | +This query demonstrates how `LEFT JOIN` handles employees who may not be assigned to any department. Employee "Tom Brown" appears in the results with `NULL` values for department information, which is crucial for HR analysis to identify unassigned employees. |
34 | 165 |
|
35 |
| -## Example |
| 166 | +## Example 3: Product Sales Report |
36 | 167 |
|
37 |
| -To create a result set of every row in the `students` table combined with the `transfer_data` table where student IDs match. And if the join condition is not met, then `NULL` values are used to fill in the columns from the `transfer_data` table. |
| 168 | +This example illustrates using `LEFT JOIN` to create a comprehensive sales report that includes all products, even those that have not been sold, which is essential for inventory management and sales analysis: |
38 | 169 |
|
39 | 170 | ```sql
|
| 171 | +-- Create products table |
| 172 | +CREATE TABLE products ( |
| 173 | + product_id INT PRIMARY KEY, |
| 174 | + product_name VARCHAR(50), |
| 175 | + category VARCHAR(30), |
| 176 | + unit_price DECIMAL(8, 2) |
| 177 | +); |
| 178 | + |
| 179 | +-- Insert product data |
| 180 | +INSERT INTO products (product_id, product_name, category, unit_price) VALUES |
| 181 | +(1, 'Laptop Computer', 'Electronics', 899.99), |
| 182 | +(2, 'Wireless Mouse', 'Electronics', 29.99), |
| 183 | +(3, 'Office Chair', 'Furniture', 199.99), |
| 184 | +(4, 'Desk Lamp', 'Furniture', 49.99), |
| 185 | +(5, 'Notebook Set', 'Stationery', 15.99); |
| 186 | + |
| 187 | +-- Create sales table |
| 188 | +CREATE TABLE sales ( |
| 189 | + sale_id INT PRIMARY KEY, |
| 190 | + product_id INT, |
| 191 | + quantity_sold INT, |
| 192 | + sale_date DATE |
| 193 | +); |
| 194 | + |
| 195 | +-- Insert sales data (note: not all products have sales) |
| 196 | +INSERT INTO sales (sale_id, product_id, quantity_sold, sale_date) VALUES |
| 197 | +(1001, 1, 5, '2024-01-10'), |
| 198 | +(1002, 2, 15, '2024-01-12'), |
| 199 | +(1003, 1, 3, '2024-01-15'), |
| 200 | +(1004, 4, 8, '2024-01-18'); |
| 201 | + |
| 202 | +-- LEFT JOIN to show all products with their sales performance |
40 | 203 | SELECT
|
41 |
| - students.first_name, |
42 |
| - students.last_name, |
43 |
| - students.overall_gpa, |
44 |
| - transfer_data.overal_gpa |
45 |
| -FROM students |
46 |
| -LEFT JOIN transfer_data |
47 |
| - ON students.student_id = transfer_data.student_id; |
| 204 | + p.product_id, |
| 205 | + p.product_name, |
| 206 | + p.category, |
| 207 | + p.unit_price, |
| 208 | + COALESCE(SUM(s.quantity_sold), 0) AS total_quantity_sold, |
| 209 | + COALESCE(SUM(s.quantity_sold * p.unit_price), 0) AS total_revenue |
| 210 | +FROM products p |
| 211 | +LEFT JOIN sales s ON p.product_id = s.product_id |
| 212 | +GROUP BY p.product_id, p.product_name, p.category, p.unit_price |
| 213 | +ORDER BY total_revenue DESC; |
| 214 | +``` |
| 215 | + |
| 216 | +The output by this code will be: |
| 217 | + |
| 218 | +```shell |
| 219 | +| product_id | product_name | category | unit_price | total_quantity_sold | total_revenue | |
| 220 | +|------------|------------------|--------------|------------|----------------------|----------------| |
| 221 | +| 1 | Laptop Computer | Electronics | 899.99 | 8 | 7199.92 | |
| 222 | +| 2 | Wireless Mouse | Electronics | 29.99 | 15 | 449.85 | |
| 223 | +| 4 | Desk Lamp | Furniture | 49.99 | 8 | 399.92 | |
| 224 | +| 5 | Notebook Set | Stationery | 15.99 | 0 | 0.00 | |
| 225 | +| 3 | Office Chair | Furniture | 199.99 | 0 | 0.00 | |
48 | 226 | ```
|
49 | 227 |
|
50 |
| -The result set will only include last name, first name, and both GPAs. |
| 228 | +This query generates a complete sales report showing all products, including those with zero sales. The use of `COALESCE` function handles `NULL` values by converting them to zero, making the report more readable and suitable for business analysis. |
| 229 | + |
| 230 | +## Frequently Asked Questions |
| 231 | + |
| 232 | +### 1. What is the difference between `LEFT JOIN` and `INNER JOIN`? |
| 233 | + |
| 234 | +`LEFT JOIN` returns all records from the left table and matching records from the right table, while `INNER JOIN` only returns records that have matches in both tables. |
| 235 | + |
| 236 | +### 2. Can I use multiple LEFT JOINs in a single query? |
| 237 | + |
| 238 | +Yes, you can chain multiple `LEFT JOIN`s together. Each `LEFT JOIN` operates on the result of the previous join, allowing you to combine data from multiple tables while preserving records from the leftmost table. |
| 239 | + |
| 240 | +### 3. What happens when the join condition returns multiple matches? |
| 241 | + |
| 242 | +When multiple rows in the right table match a single row in the left table, `LEFT JOIN` returns all matching combinations. This can result in duplicate rows from the left table, one for each matching row in the right table. |
0 commit comments