An engineering manager at Helix Systems needs a staff list for department 3.
Write a query to return each employee's name and department name for every employee assigned to that department.
Assumptions:
- The
employeestable contains every active and former employee at Helix Systems. - The
departmentstable contains every department; department 3 is identified bydepartments.id = 3. - The department condition can be expressed against either the employee's
department_idor the department'sid— both produce the same result because they are equal across the assembled rows.
Output:
- One row per qualifying employee, with columns
employee_nameanddepartment_name.
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
e.name AS employee_name,
d.name AS department_name
FROM
employees e
JOIN departments d ON e.department_id = d.id
WHERE
d.id = 3 The shape
The join pairs each employee with their department on e.department_id = d.id, and the WHERE narrows to the rows where the department side is 3. Because the ON condition forces those two columns to hold the same value on every assembled row, filtering on either side produces the same eleven-employee Sales roster.
Clause by clause
FROM employees eis the source: every active and former employee at Helix Systems.JOIN departments d ON e.department_id = d.idpairs each employee with the department row identified by theirdepartment_id. For every employee, PostgreSQL finds the matching department row and combines both into a single output row.WHERE d.id = 3filters the assembled rows to the ones whose department side is department 3 —Sales. The eleven employees assigned to that department come through; everyone else drops.SELECT e.name AS employee_name, d.name AS department_namereturns the twonamecolumns from each side. The qualifierse.andd.are mandatory because both tables have anamecolumn; the output aliases then label each column by its role.
Why this and not WHERE e.department_id = 3
Both conditions produce the exact same result. The join's ON e.department_id = d.id guarantees that on every row in the assembled result, e.department_id and d.id hold the same value. They're equated by definition. So WHERE d.id = 3 and WHERE e.department_id = 3 are equivalent filters.
Reaching through the dimension table (d.id = 3) is the more general pattern. When the filter is on an attribute the fact table doesn't carry — d.name = 'Sales', d.region = 'EMEA' — the condition has to ride on the dimension side. Writing the filter on the dimension keeps the shape consistent across cases where the criterion lives on attributes the employee row doesn't store.
You practiced applying a condition on the matched-key value. Once two tables are paired on e.department_id = d.id, those two columns hold the same value for every row in the result — the condition on either side gives the same answer.