N021-M3 Tier 2 · Core SQL · medium hr · Helix Systems

Return all three values for every employee with a manager on record

Part of Self-Joins in SQL

The problem

Helix Systems' HR reporting team needs a table showing each employee's name, their manager's name, and the department the employee belongs to.

Write a query to return all three values for every employee with a manager on record.

Assumptions:

  • The employees table contains every active and former employee at Helix Systems.
  • The departments table contains every department; each employee's department_id points to a row in departments.
  • The query brings together two relationships: each employee paired with their manager (both from employees), and each employee paired with their department.

Output:

  • One row per employee with a manager, with columns employee_name, manager_name, and department_name.
Schema · hr 4 tables
departments
id integer
name text
location text
budget numeric
salaries
id integer
employee_id integer
amount numeric
effective_date date
end_date? date
employees
id integer
name text
email text
department_id integer
manager_id? integer
hire_date date
title text
is_active boolean
job_history
id integer
employee_id integer
title text
department_id integer
start_date date
end_date? date

Run previews · Check grades

Write a query, then run it to see results here.

Worked solution Try it yourself first
Solution query
SELECT
  e.name AS employee_name,
  m.name AS manager_name,
  d.name AS department_name
FROM
  employees e
  JOIN employees m ON e.manager_id = m.id
  JOIN departments d ON e.department_id = d.id

The shape

Three aliases name three roles in the query: e is the employee, m is the manager (also from employees), and d is the department from departments. The self-join supplies the manager name; a second, ordinary join supplies the department name.

Clause by clause

  • SELECT e.name AS employee_name, m.name AS manager_name, d.name AS department_name pulls name from each of the three aliases. Three different roles, three labeled columns.
  • FROM employees e reads employees in the employee role.
  • JOIN employees m ON e.manager_id = m.id reads employees again in the manager role. This is the self-join; both sides reference the same physical table, distinguished only by the aliases.
  • JOIN departments d ON e.department_id = d.id reads departments and links each employee to their department. The join is on the employee's department_id, not the manager's — the prompt asks for the department the employee belongs to.

Why this and not JOIN departments d ON m.department_id = d.id

Which alias the department join keys to decides whose department appears in the result. e.department_id = d.id pairs each row with the employee's department (Marcus Reid → Engineering). m.department_id = d.id would pair each row with the manager's department instead (Marcus Reid → whatever department Sarah Chen sits in). The prompt asks for the employee's department, so the join keys to e.

The trap

Once two aliases share a foreign key column (department_id), every downstream join has to commit to one of them. The query parses either way and returns the same column count and similar row count, so the mistake doesn't surface as an error. Trace which role the prompt is asking about before writing the second join's ON clause.

You practiced combining a self-join with a regular join. Aliases keep the roles distinct — e, m, and d each name a different participant, even when two of them come from the same table.

How you actually get good at SQL

Reading explains SQL. Writing it, over and over with instant feedback, is what makes you fluent.

That's the whole SQLMaxx loop: 600+ real problems, instant AI feedback, mastery you can actually see, and spaced review that won't let you forget.

A stack of SQL practice problem cards, the top card showing an employees table.
615 problems · 66 concepts

Real problems. Not toy examples.

615 hand-built problems spanning all 66 concepts, from basic SELECTs to window functions, built on real schemas and real business questions, the kind you'll actually get asked on the job. Enough reps to make SQL automatic.

A retro computer showing a SQL query marked correct with a green checkmark.
Instant AI feedback

Write a query. Know if it's right in one second.

No copying an answer and hoping it clicked. The AI grader checks your real query against real data, catches exactly what's wrong, and explains the fix in plain English, like a senior analyst reading over your shoulder on every problem.

A circular mastery progress dial filling from blue to green, the SQLMaxx diamond at its center.
Mastery tracking

Stop guessing whether you actually know it.

SQLMaxx tracks every concept and shows you what you've mastered and what's still shaky. Your skills fill in one concept at a time, so 'I think I get joins' becomes something you can prove.

A SQL query editor circled by a blue return arrow with a clock, scheduled to come back for review.
Spaced review

Learn it once. Keep it for good.

Most of what you learn this week fades by next week. So when a concept comes due for review, SQLMaxx hands you a fresh problem to solve from a blank editor, not a flashcard to re-read. A research-backed spaced-repetition algorithm (FSRS) times each return for right before you'd forget, so your SQL is still there months later, when the interview or the job actually needs it.

Practice, feedback, mastery, review. That's the loop that turns reading into real skill.

Start free

No account, no credit card. Start solving in under a minute.