3-Row Moving Average of Salaries (Explicit ROWS Frame)
Within each department, ordered by hire_date, compute the moving average of salary over the current row and the two before it (a 3-row trailing window). Return department_name, first_name, last_name, hire_date, salary, moving_avg_3 (rounded to 2) — ordered by department_name, hire_date, employee_id.
- Window functions
- Joins
- Aggregation
- Sorting
Interview brief
Understand the request
Within each department, ordered by hire_date, compute the moving average of salary over the current row and the two before it (a 3-row trailing window). Return department_name, first_name, last_name, hire_date, salary, moving_avg_3 (rounded to 2) — ordered by department_name, hire_date, employee_id.
Data you will use
Review the relevant tables before deciding how to join, filter, or aggregate them.
employees
employee_idINTEGERfirst_nameVARCHAR(50)last_nameVARCHAR(50)hire_dateDATEsalaryINTEGERdepartment_idINTEGER
departments
department_idINTEGERdepartment_nameVARCHAR(50)
Hints, when you need them
Open one clue at a time so you still do the reasoning.
Hint 1
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW = at most 3 rows (this one + two before).
Hint 2
Early rows in each partition average over fewer than 3 rows — that is expected.
Hint 3
Change the number to widen/narrow the window (e.g. 6 PRECEDING for a 7-row average).
Verified SQL answer
Attempt the problem first, then compare structure and reasoning—not just syntax.
Reveal solution and explanation
SELECT d.department_name, e.first_name, e.last_name, e.hire_date, e.salary, ROUND(AVG(e.salary) OVER (PARTITION BY e.department_id ORDER BY e.hire_date, e.employee_id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 2) AS moving_avg_3 FROM employees e INNER JOIN departments d ON e.department_id = d.department_id ORDER BY d.department_name, e.hire_date, e.employee_id;Why this works
Moving averages smooth noisy series. The explicit ROWS frame is what makes it a true N-row trailing average; without it you get the default (often a running average). Frames are the single most under-used part of window functions.
Expected result
Use this output to verify values, aliases, ordering, and row count.
| department_name | first_name | last_name | hire_date | salary | moving_avg_3 |
|---|---|---|---|---|---|
| Engineering | Michael | Scott | 2019-03-20 | 180000 | 180000 |
| Engineering | David | Martinez | 2020-02-14 | 130000 | 155000 |
| Engineering | Emily | Chen | 2020-05-18 | 125000 | 145000 |
| Engineering | Robert | Williams | 2021-01-10 | 95000 | 116666.67 |
| Engineering | Lisa | Anderson | 2021-03-22 | 90000 | 103333.33 |
| Engineering | Amanda | White | 2022-03-10 | 75000 | 86666.67 |
| Executive | Jennifer | King | 2018-01-15 | 250000 | 250000 |
| Finance | Jessica | Moore | 2020-04-08 | 105000 | 105000 |
| Finance | Daniel | Lee | 2021-07-15 | 70000 | 87500 |
| Human Resources | Patricia | Davis | 2019-11-05 | 95000 | 95000 |
Previewing 10 of 15 expected rows. Run the query in the editor to inspect the full result.
Learn the concepts behind this answer
Strengthen your understanding with these targeted learning topics: