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

Return the employee ID and name for every employee who has at least one direct report on record

Part of Subqueries in WHERE (IN, EXISTS, ANY, ALL) in SQL

The problem

Helix Systems' HR team needs to identify managers for an org-chart audit.

Write a query to return the employee ID and name for every employee who has at least one direct report on record.

Assumptions:

  • The employees table contains every active and former employee at Helix Systems.
  • An employee is a manager if at least one other employee's manager_id matches their id.
  • The check is against the same table — both alias instances of employees come from the same source.

Output:

  • One row per manager, with columns id and 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
  id,
  name
FROM
  employees e
WHERE
  EXISTS (
    SELECT
      1
    FROM
      employees r
    WHERE
      r.manager_id = e.id
  )

The shape

The check is whether any other row in the same employees table has its manager_id pointing back at the current employee's id. EXISTS with the table aliased twice expresses that self-reference directly. One alias for the candidate manager, another for the potential report.

Clause by clause

  • SELECT id, name FROM employees e reads every employee at Helix Systems and aliases this instance as e. e represents the candidate manager — the outer row whose id might appear as someone else's manager_id.
  • WHERE EXISTS (SELECT 1 FROM employees r WHERE r.manager_id = e.id) is the correlated test. r is a second alias of the same table, representing a potential direct report. For each outer e.id, PostgreSQL looks inside the table for any row where r.manager_id matches. If one is found, the outer row passes. If none is found, the row drops.
  • The two aliases are what make the self-reference unambiguous. Without them, the inner WHERE manager_id = id would be checking a row against itself. e.id and r.manager_id are values from two row contexts of the same table; the aliases give each context its own name.

Why this and not IN (SELECT manager_id FROM employees)

For this prompt IN produces the same result and is shorter to type. EXISTS reads more naturally on hierarchical "is X a parent of anything" questions because the outer question maps directly onto the inner phrasing "does a row exist where manager_id = this employee's id."

The quieter advantage: manager_id is NULL for top-level employees, so the negation NOT IN (SELECT manager_id FROM employees) would silently return zero rows. NOT EXISTS doesn't have that hazard. Picking EXISTS for the positive case keeps the shape consistent with the safer negation.

You practiced EXISTS against the same table the outer query is reading from. The recurring shape: hierarchical "is X a manager / parent / referrer" tests use a correlated EXISTS that joins the table to itself through the foreign-key column.

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.