cswork / libraryOpen practice workspace

Coding questions · ByteDance

Find top-paid employee per department

This question evaluates proficiency in data manipulation and SQL querying, testing concepts such as selecting the latest records, group-wise aggregation for top-N per group, handling duplicates and salary history, and deterministic tie-breaking when an employee appears in multiple departments.

Given the following tables:

  1. employees
  • employee_id INT PRIMARY KEY
  • employee_name VARCHAR
  1. employee_department
  • employee_id INT
  • department_id INT
  • salary NUMERIC(12,2)
  • updated_at TIMESTAMP

Assumptions:

  • An employee can appear in multiple departments (multiple rows with different department_id).
  • There may also be multiple records for the same (employee_id, department_id) over time; the latest record is the one with the greatest updated_at.

Task A:

  • Write a SQL query to return the top 1 highest-paid employee in each department.
  • Output columns: department_id, employee_id, employee_name, salary.

Task B (follow-ups):

  • If an employee is in multiple departments, does that change the correctness of “top 1 per department”? Why or why not?
  • What data issues could actually change the result (e.g., duplicates, salary history)?
  • If the same employee ends up being top-paid in multiple departments but you want each employee to appear at most once in the final output, how would you modify the query? (Define a deterministic tie-break rule.)

Find top-paid employee per department

Return the top 1 highest-paid employee in each department using the most recent row per (employee_id, department_id). Output: department_id, employee_id, employee_name, salary. Then discuss whether multi-department employees affect correctness, what data issues could change results, and how to modify the query so each employee appears at most once with a deterministic tie-break.

Table employees

columntypeconstraints
employee_idINTPRIMARY KEY
employee_nameVARCHAR

Sample data:

employee_idemployee_name
1Alice
2Bob
3Carol
4Dave
5Erin

Table employee_department

columntypeconstraints
employee_idINT
department_idINT
salaryNUMERIC(12,2)
updated_atTIMESTAMP

Sample data:

department_idemployee_idsalaryupdated_at
1011000002024-01-01 10:00:00
1011100002024-06-01 09:00:00
1021150002024-05-01 12:00:00
1031150002024-05-02 08:30:00
202800002023-12-01 12:00:00
202990002024-02-01 09:15:00
2041200002024-04-01 11:00:00
2051200002024-04-02 10:00:00
3011300002024-03-01 09:00:00
3041250002024-03-02 09:00:00
4011050002024-04-15 13:45:00
405950002024-03-01 14:00:00

Expected output

One row per department with the employee who has the highest current salary in that department. Current means the row with the greatest updated_at per (employee_id, department_id). If multiple employees tie on salary within a department, break ties deterministically by smaller employee_id.

department_idemployee_idemployee_namesalary
102Bob115000
204Dave120000
301Alice130000
401Alice105000

Hints

  1. Use a window function to isolate the latest row per (employee_id, department_id): ROW_NUMBER() OVER (PARTITION BY employee_id, department_id ORDER BY updated_at DESC, salary DESC). Keep rn = 1.
  2. Then rank employees within each department by salary DESC and break ties deterministically (e.g., employee_id ASC). Keep dept_rn = 1.
  3. Join to employees to fetch employee_name for the winners.
  4. An employee being in multiple departments does not affect correctness for 'top 1 per department' because ranking is partitioned by department.
  5. Data issues that can change results: duplicate or conflicting rows for the same (employee_id, department_id, updated_at), identical timestamps across updates, NULL updated_at, out-of-order timestamps, and salary ties without a defined tie-breaker.
  6. To ensure each employee appears at most once globally: after the 'latest' step, pick a single department per employee with ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY salary DESC, department_id ASC) = 1 and filter to those; note this may leave some departments without a row. To still keep one row per department while enforcing uniqueness, you need an iterative assignment (e.g., a recursive CTE) that replaces suppressed top employees with the next-ranked candidate per department.
  7. Performance: consider indexes on employee_department(employee_id, department_id, updated_at DESC) and on employee_department(department_id, salary DESC).