LEFT JOIN in MySQL - Time & Space Complexity
When using LEFT JOIN in SQL, it's important to understand how the time to run the query grows as the tables get bigger.
We want to know how the number of rows in each table affects the work the database does.
Analyze the time complexity of the following code snippet.
SELECT a.id, b.value
FROM tableA a
LEFT JOIN tableB b ON a.id = b.a_id;
This query returns all rows from tableA and matches rows from tableB where the IDs match.
Look at what repeats as the query runs:
- Primary operation: For each row in tableA, the database looks for matching rows in tableB.
- How many times: This happens once for every row in tableA.
As tableA grows, the database must check more rows. For each row in tableA, it searches tableB for matches.
| Input Size (rows in tableA) | Approx. Operations |
|---|---|
| 10 | About 10 searches in tableB |
| 100 | About 100 searches in tableB |
| 1000 | About 1000 searches in tableB |
Pattern observation: The work grows roughly in direct proportion to the size of tableA.
Time Complexity: O(n * m)
This means the work grows roughly by multiplying the number of rows in tableA (n) by the number of rows in tableB (m).
[X] Wrong: "LEFT JOIN only depends on the size of the first table, so it's always fast if the first table is small."
[OK] Correct: Even if the first table is small, the database must still search the second table for each row, so the second table's size also affects the time.
Understanding how LEFT JOIN scales helps you explain query performance clearly and shows you can think about how databases handle data behind the scenes.
What if we added an index on the join column in tableB? How would the time complexity change?
Practice
LEFT JOIN do in SQL?Solution
Step 1: Understand LEFT JOIN behavior
A LEFT JOIN keeps all rows from the left table regardless of matches in the right table.Step 2: Check what happens with unmatched rows
If no matching row exists in the right table, the result shows NULL for right table columns.Final Answer:
Returns all rows from the left table and matching rows from the right table, NULL if no match. -> Option DQuick Check:
LEFT JOIN = all left rows + matched right rows [OK]
- Confusing LEFT JOIN with INNER JOIN
- Thinking it returns all right table rows
- Assuming unmatched rows are dropped
Solution
Step 1: Review standard LEFT JOIN syntax
The correct syntax uses LEFT JOIN followed by ON condition to specify matching columns.Step 2: Check each option
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id; uses correct syntax: LEFT JOIN with ON clause. SELECT * FROM table1 JOIN LEFT table2 ON table1.id = table2.id; has JOIN LEFT which is invalid. SELECT * FROM table1 LEFT OUTER JOIN table2 WHERE table1.id = table2.id; uses WHERE instead of ON, which is incorrect for JOIN condition. SELECT * FROM table1 LEFT JOIN table2 WHERE table1.id = table2.id; uses WHERE instead of ON, invalid syntax.Final Answer:
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id; -> Option AQuick Check:
LEFT JOIN syntax = LEFT JOIN ... ON ... [OK]
- Using JOIN LEFT instead of LEFT JOIN
- Using WHERE instead of ON for join condition
- Putting join condition directly in WHERE after table
Employees(id, name)Departments(id, dept_name, emp_id)What is the output of this query?
SELECT e.name, d.dept_name FROM Employees e LEFT JOIN Departments d ON e.id = d.emp_id ORDER BY e.id;
Assuming:
Employees: (1, 'Alice'), (2, 'Bob'), (3, 'Carol')
Departments: (10, 'HR', 1), (20, 'IT', 3)
Solution
Step 1: Match Employees with Departments using LEFT JOIN
LEFT JOIN keeps all Employees. For each employee, it tries to find a matching department where e.id = d.emp_id.Step 2: Check matches and NULLs
'Alice' (id=1) matches department 'HR' (emp_id=1). 'Bob' (id=2) has no matching department, so dept_name is NULL. 'Carol' (id=3) matches 'IT' (emp_id=3).Final Answer:
[('Alice', 'HR'), ('Bob', NULL), ('Carol', 'IT')] -> Option CQuick Check:
LEFT JOIN keeps all left rows, unmatched right columns NULL [OK]
- Assuming unmatched rows are dropped
- Mixing up emp_id and id columns
- Ignoring ORDER BY effect
SELECT a.id, b.value FROM tableA a LEFT JOIN tableB b ON a.id = b.id WHERE b.value > 10;
Solution
Step 1: Understand effect of WHERE on LEFT JOIN
LEFT JOIN keeps all rows from tableA, but WHERE b.value > 10 excludes rows where b.value is NULL (no match), effectively turning it into INNER JOIN.Step 2: Identify the error
The error is using WHERE to filter on right table columns after LEFT JOIN, which removes unmatched rows.Final Answer:
The WHERE clause filters out rows where b.value is NULL, defeating LEFT JOIN purpose. -> Option AQuick Check:
WHERE on right table column after LEFT JOIN removes unmatched rows [OK]
- Using WHERE instead of ON for right table filters
- Confusing LEFT JOIN with INNER JOIN
- Ignoring NULLs in join columns
Products(product_id, name)Sales(sale_id, product_id, quantity)You want to list all products with total quantity sold, including products with zero sales.
Which query correctly uses LEFT JOIN to achieve this?
Solution
Step 1: Use LEFT JOIN from Products to Sales
To include all products even with no sales, LEFT JOIN Sales to Products on product_id.Step 2: Aggregate sales quantity and group by product
Use SUM(s.quantity) to total sales per product. Group by p.product_id to get one row per product.Final Answer:
SELECT p.name, SUM(s.quantity) FROM Products p LEFT JOIN Sales s ON p.product_id = s.product_id GROUP BY p.product_id; -> Option BQuick Check:
LEFT JOIN + SUM + GROUP BY lists all products with total sales [OK]
- Using INNER JOIN excludes products with zero sales
- Joining Sales to Products reverses LEFT JOIN logic
- Filtering in WHERE removes unmatched rows
Ready to prove it?
Pass the test and this pattern moves unknown
