N039-M3 Tier 3 · Intermediate · medium hr · Helix Systems

Return the ID, name, department ID, and hire date of every employee, plus the employee's seniority rank within their department

Part of ROW_NUMBER, RANK, DENSE_RANK in SQL

The problem

Helix Systems' HR team tracks employee seniority within each department based on hire date — the earliest hire in a department holds rank 1.

Write a query to return the ID, name, department ID, and hire date of every employee, plus the employee's seniority rank within their department.

Assumptions:

  • The employees table has one row per employee with an id, a name, a department_id, and a hire_date.
  • Within each department, the earliest hire_date receives seniority rank 1, the next-earliest receives 2, and so on. Rank values restart for each department.
  • Every employee in a department receives a different seniority rank; if two employees share the same hire_date, they receive consecutive numbers in some order.

Output:

  • One row per employee, with columns id, name, department_id, hire_date, and seniority_rank.
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,
  department_id,
  hire_date,
  ROW_NUMBER() OVER (
    PARTITION BY
      department_id
    ORDER BY
      hire_date
  ) AS seniority_rank
FROM
  employees

The shape

ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY hire_date) numbers each department's employees from earliest hire to latest, starting at 1 per department. The longest-tenured employee in any department gets 1, the next-hired gets 2, and the sequence runs independently inside every department.

Clause by clause

  • SELECT id, name, department_id, hire_date, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY hire_date) AS seniority_rank returns each employee's identifying columns and their seniority position. PARTITION BY department_id creates one window per department; ORDER BY hire_date (ascending, the default) sorts within each window from earliest to latest hire date; ROW_NUMBER assigns the positions 1, 2, 3, ... per department.
  • FROM employees reads every employee. No filter; every employee gets a seniority rank inside their own department.

Why ascending ORDER BY hire_date and not descending

The earliest hire date is the smallest value in the column, so ascending order puts the most-tenured person first. Descending order would put the newest hire at rank 1, which inverts the seniority semantics. Whenever the rank is meant to read as "rank 1 = most senior," the sort direction has to match how the underlying column orders the population. For hire dates, earliest is most senior, so ascending is the right direction.

The trap

If two employees in the same department share an exact hire_date, ROW_NUMBER will give them different positions arbitrarily. Whoever the database engine returns first gets 1 and the other gets 2, with no semantic reason for the choice. If the seniority report needs a deterministic tie-break, add a secondary sort like ORDER BY hire_date, id. If the report needs tied employees to share a rank, switch to RANK or DENSE_RANK. ROW_NUMBER is the right tool when the consumer needs exactly one employee per position, and the tie-break can be arbitrary.

You practiced ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ... ASC) — the earliest-or-latest-per-group shape, partitioned by an entity column and ordered by a timestamp.

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.