Bird
Raised Fist0
MySQLquery~10 mins

JOIN with aggregate functions in MySQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - JOIN with aggregate functions
Start with two tables
↓
Perform JOIN on matching keys
↓
Group rows if needed
↓
Apply aggregate functions (SUM, COUNT, AVG, etc.)
↓
Return aggregated results with joined data
This flow shows how two tables are joined, then aggregate functions are applied on the joined data to summarize information.
Execution Sample
MySQL
SELECT d.department_name, COUNT(e.employee_id) AS employee_count
FROM departments d
JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_name;
This query joins departments with employees and counts how many employees are in each department.
Execution Table
StepActionTables InvolvedIntermediate ResultAggregate Result
1Start with departments and employees tablesdepartments, employeesdepartments (4 rows), employees (6 rows)
2Perform JOIN on department_iddepartments JOIN employeesJoined rows (6 rows): each employee matched with their department
3Group rows by department_nameJoined rowsGroups: Sales(2 rows), HR(1 row), IT(3 rows)
4Apply COUNT(employee_id) per groupGrouped rowsSales:2, HR:1, IT:3
5Return final result with department_name and employee_countAggregated data[{Sales,2}, {HR,1}, {IT,3}]
6Query endsAll groups counted, query complete
💡 All joined rows processed and aggregated by department_name, query returns counts per department.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
departments4 rows4 rowsGrouped by nameGrouped by nameGrouped by name
employees6 rows6 rowsGrouped by departmentGrouped by departmentGrouped by department
joined_rowsN/A6 rows6 rows grouped6 rows grouped6 rows grouped
groupsN/AN/A3 groups3 groups with counts3 groups with counts
employee_countN/AN/AN/ACounts calculatedCounts calculated
Key Moments - 3 Insights
Why do we need to GROUP BY after JOIN when using aggregate functions?
Because aggregate functions like COUNT summarize data per group, GROUP BY tells SQL how to group joined rows before aggregation, as shown in execution_table step 3.
What happens if we forget to GROUP BY when using COUNT with JOIN?
The COUNT would apply to the entire joined result, giving one total count instead of counts per department. This is why step 3 grouping is essential.
Does JOIN increase the number of rows before aggregation?
Yes, JOIN combines matching rows from both tables, often increasing rows as seen in step 2 where 6 joined rows appear from 4 and 6 original rows.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, how many rows are in the joined result after step 2?
A4 rows
B3 rows
C6 rows
D1 row
💡 Hint
Check the 'Intermediate Result' column at step 2 in the execution_table.
At which step does the query group rows by department_name?
AStep 2
BStep 3
CStep 4
DStep 5
💡 Hint
Look for the 'Group rows by department_name' action in the execution_table.
If we remove GROUP BY, what would happen to the employee_count?
AIt would count all employees in one total
BIt would count employees per department
CIt would cause a syntax error
DIt would return zero
💡 Hint
Refer to key_moments about the importance of GROUP BY with aggregate functions.
Concept Snapshot
JOIN with aggregate functions:
- JOIN combines rows from two tables on matching keys.
- GROUP BY groups joined rows by specified columns.
- Aggregate functions (COUNT, SUM, AVG) summarize each group.
- Without GROUP BY, aggregates apply to entire joined set.
- Use GROUP BY to get meaningful summaries per group.
Full Transcript
This visual execution shows how a SQL query joins two tables, groups the joined rows, and applies aggregate functions. First, the departments and employees tables are joined on department_id, producing 6 joined rows. Then, rows are grouped by department_name to prepare for aggregation. The COUNT function counts employees in each department group. Finally, the query returns the department names with their employee counts. Key points include the necessity of GROUP BY to get counts per department and how JOIN increases rows before aggregation.

Practice

(1/5)
1. What does the following SQL query do?
SELECT department, COUNT(employee_id) FROM employees JOIN departments ON employees.dept_id = departments.id GROUP BY department;
easy
A. Counts employees in each department by joining employees and departments tables.
B. Lists all employees without grouping by department.
C. Calculates the average salary per department.
D. Deletes employees who are not assigned to any department.

Solution

  1. Step 1: Understand the JOIN operation

    The query joins the employees and departments tables using the department ID to combine related data.
  2. Step 2: Analyze the GROUP BY and COUNT

    It groups the results by department and counts the number of employees in each group.
  3. Final Answer:

    Counts employees in each department by joining employees and departments tables. -> Option A
  4. Quick Check:

    JOIN + GROUP BY + COUNT = Employee count per department [OK]
Hint: JOIN tables, GROUP BY key, then apply COUNT [OK]
Common Mistakes:
  • Ignoring GROUP BY causes wrong aggregation
  • Using COUNT without JOIN returns incomplete data
  • Confusing COUNT with SUM or AVG
2. Which of the following is the correct syntax to get the total sales per customer using JOIN and SUM?
SELECT customers.name, SUM(orders.amount) FROM customers JOIN orders ON customers.id = orders.customer_id GROUP BY customers.name;
easy
A. SELECT customers.name, SUM(orders.amount) FROM customers LEFT JOIN orders GROUP BY customers.name;
B. SELECT customers.name, SUM(orders.amount) FROM customers JOIN orders WHERE customers.id = orders.customer_id GROUP BY customers.name;
C. SELECT customers.name, SUM(orders.amount) FROM customers JOIN orders ON customers.id = orders.customer_id GROUP BY customers.name;
D. SELECT customers.name, SUM(orders.amount) FROM customers, orders GROUP BY customers.name;

Solution

  1. Step 1: Check JOIN syntax

    SELECT customers.name, SUM(orders.amount) FROM customers JOIN orders ON customers.id = orders.customer_id GROUP BY customers.name; uses correct INNER JOIN syntax with ON clause to link customers and orders.
  2. Step 2: Verify GROUP BY and SUM usage

    SELECT customers.name, SUM(orders.amount) FROM customers JOIN orders ON customers.id = orders.customer_id GROUP BY customers.name; correctly groups by customer name and sums order amounts.
  3. Final Answer:

    SELECT customers.name, SUM(orders.amount) FROM customers JOIN orders ON customers.id = orders.customer_id GROUP BY customers.name; -> Option C
  4. Quick Check:

    JOIN with ON + GROUP BY + SUM = Correct syntax [OK]
Hint: Use JOIN ... ON ... with GROUP BY for aggregates [OK]
Common Mistakes:
  • Using WHERE instead of ON in JOIN
  • Missing ON clause causes syntax error
  • Grouping by wrong column
3. Given tables:
employees(id, name, dept_id)
departments(id, department)
What is the output of this query?
SELECT d.department, COUNT(e.id) AS emp_count FROM employees e LEFT JOIN departments d ON e.dept_id = d.id GROUP BY d.department ORDER BY emp_count DESC;
medium
A. Syntax error due to missing GROUP BY column.
B. List of departments with employee counts, including departments with zero employees.
C. List of employees with their department names.
D. List of departments with employee counts, excluding departments with zero employees.

Solution

  1. Step 1: Understand LEFT JOIN effect

    FROM employees e LEFT JOIN departments d ON e.dept_id = d.id includes all employees and matching departments if they exist. Departments with no employees do not appear because no employee row matches them.
  2. Step 2: GROUP BY and COUNT behavior

    Grouping by d.department counts employees only for departments that have at least one employee (count >=1). Departments with zero employees are excluded.
  3. Final Answer:

    List of departments with employee counts, excluding departments with zero employees. -> Option D
  4. Quick Check:

    LEFT JOIN from employees + GROUP BY department excludes zero counts [OK]
Hint: LEFT JOIN keeps all left rows, COUNT counts matches [OK]
Common Mistakes:
  • Assuming INNER JOIN behavior excludes zero counts
  • Confusing COUNT(*) with COUNT(column)
  • Ignoring NULL values in grouping
4. Identify the error in this query:
SELECT d.department, COUNT(e.id) FROM employees e JOIN departments d ON e.dept_id = d.id WHERE e.salary > 50000 GROUP BY e.dept_id;
medium
A. GROUP BY should use d.department instead of e.dept_id.
B. Missing HAVING clause for salary filter.
C. COUNT(e.id) cannot be used with JOIN.
D. ON clause is incorrect syntax.

Solution

  1. Step 1: Check GROUP BY columns

    The SELECT lists d.department but GROUP BY uses e.dept_id, causing mismatch.
  2. Step 2: Fix GROUP BY to match SELECT

    GROUP BY should use d.department or include it to avoid errors.
  3. Final Answer:

    GROUP BY should use d.department instead of e.dept_id. -> Option A
  4. Quick Check:

    GROUP BY columns must match SELECT non-aggregates [OK]
Hint: GROUP BY columns must match SELECT non-aggregates [OK]
Common Mistakes:
  • Grouping by wrong or missing columns
  • Using WHERE instead of HAVING for aggregates
  • Incorrect JOIN ON syntax
5. You have tables:
orders(order_id, customer_id, amount)
customers(customer_id, name)
Write a query to find customers who have total orders amount greater than 1000, including customers with no orders showing zero total.
Which query is correct?
hard
A. SELECT c.name, SUM(o.amount) AS total FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id WHERE total > 1000 GROUP BY c.name;
B. SELECT c.name, COALESCE(SUM(o.amount), 0) AS total FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.name HAVING total > 1000;
C. SELECT c.name, SUM(o.amount) AS total FROM customers c JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.name HAVING total > 1000;
D. SELECT c.name, SUM(o.amount) AS total FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.name WHERE total > 1000;

Solution

  1. Step 1: Use LEFT JOIN to include customers without orders

    LEFT JOIN ensures all customers appear, even if no matching orders exist.
  2. Step 2: Use COALESCE to convert NULL sums to zero and HAVING to filter totals

    COALESCE replaces NULL with 0; HAVING filters groups by aggregate result.
  3. Final Answer:

    SELECT c.name, COALESCE(SUM(o.amount), 0) AS total FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.name HAVING total > 1000; -> Option B
  4. Quick Check:

    LEFT JOIN + COALESCE + HAVING filters totals correctly [OK]
Hint: Use LEFT JOIN + COALESCE + HAVING for conditional aggregates [OK]
Common Mistakes:
  • Using WHERE instead of HAVING for aggregate filters
  • Ignoring NULL sums for customers without orders
  • Using INNER JOIN excludes customers with zero orders
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard