Helix Systems' HR director is reviewing organisational staffing levels ahead of the annual workforce plan.
Write a query to return each department_id and the number of employees assigned to it.
Assumptions:
- The
employeestable contains every active and former employee at Helix Systems. department_idlinks each employee to their department.
Output:
- One row per distinct
department_id, with columnsdepartment_idandemployee_count.
Schema · hr 4 tables
Run previews · Check grades
Write a query, then run it to see results here.
Worked solution Try it yourself first
SELECT
department_id,
COUNT(*) AS employee_count
FROM
employees
GROUP BY
department_id The shape
GROUP BY department_id collapses the employees table into one row per department, and COUNT(*) counts the employees that landed in each one. The department_id column on the employees table is what links each person to their org unit, and grouping by it is what turns a row-per-employee table into a row-per-department headcount.
Clause by clause
SELECT department_id, COUNT(*) AS employee_countreturns the department identifier alongside its headcount.department_idis in the SELECT list and inGROUP BY, which is the rule whenever you mix a plain column with an aggregate.FROM employeesreads every active and former employee record.GROUP BY department_idis the partitioning step. Department 1 ends up with 17 rows in its bucket, department 3 with 11, and so on.COUNT(*)then runs once per bucket.
Why this and not COUNT(DISTINCT department_id)
COUNT(DISTINCT department_id) FROM employees would return a single number: how many departments exist. That answers a different question. The HR director needs the size of each department, not the size of the department list. The shape the workforce plan needs is one row per department with its headcount, and that requires GROUP BY.
You practiced grouping a fact table (employees) by its foreign-key column (department) to get a per-parent count. The recurring shape behind every "how many X per Y" question in any one-to-many relationship.