Talentd
FleetCode
Make and follow sheets.Sign in

Find Consistently Improving Employees solution and explanation

MediumDatabase6 min read58.4% acceptanceUpdated 16 Oct 2026
Leetcode MEDIUM 3580 - RANKING in SQL - Consistently Improving Employees | Everyday Data ScienceEveryday Data Science · 11:24 · 1K viewsWatch on YouTube
4 more videos on this problem
  1. Leetcode MEDIUM 3580 - RANKING in SQL - Consistently Improving Employees | Everyday Data ScienceEveryday Data Science · 11:24 · 1K views
  2. LeetCode SQL 3580 - Find Consistently Improving EmployeesAnalyticHub · 15:23 · 145 views
  3. LeetCode 3580 – Find Consistently Improving Employees | SQL Interview Question ExplainedInsightVanta · 15:34 · 118 views
  4. Master SQL Window Functions: ROW_NUMBER & LAG | LeetCode 3580 SolutionVivek The Analyst · 22:46 · 50 views
  5. LeetCode. Sql, 3580. Find Consistently Improving Employees, уровень MEDIUMДиванная аналитика · 20:41 · 1 view

The problem

Table: employees

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| employee_id | int     |
| name        | varchar |
+-------------+---------+
employee_id is the unique identifier for this table.
Each row contains information about an employee.

Table: performance_reviews

+-------------+------+
| Column Name | Type |
+-------------+------+
| review_id   | int  |
| employee_id | int  |
| review_date | date |
| rating      | int  |
+-------------+------+
review_id is the unique identifier for this table.
Each row represents a performance review for an employee. The rating is on a scale of 1-5 where 5 is excellent and 1 is poor.

Write a solution to find employees who have consistently improved their performance over their last three reviews.

  • An employee must have at least 3 review to be considered
  • The employee's last 3 reviews must show strictly increasing ratings (each review better than the previous)
  • Use the most recent 3 reviews based on review_date for each employee
  • Calculate the improvement score as the difference between the latest rating and the earliest rating among the last 3 reviews

Return the result table ordered by improvement score in descending order, then by name in ascending order.

The result format is in the following example.

Example:

Input:

employees table:

+-------------+----------------+
| employee_id | name           |
+-------------+----------------+
| 1           | Alice Johnson  |
| 2           | Bob Smith      |
| 3           | Carol Davis    |
| 4           | David Wilson   |
| 5           | Emma Brown     |
+-------------+----------------+

performance_reviews table:

+-----------+-------------+-------------+--------+
| review_id | employee_id | review_date | rating |
+-----------+-------------+-------------+--------+
| 1         | 1           | 2023-01-15  | 2      |
| 2         | 1           | 2023-04-15  | 3      |
| 3         | 1           | 2023-07-15  | 4      |
| 4         | 1           | 2023-10-15  | 5      |
| 5         | 2           | 2023-02-01  | 3      |
| 6         | 2           | 2023-05-01  | 2      |
| 7         | 2           | 2023-08-01  | 4      |
| 8         | 2           | 2023-11-01  | 5      |
| 9         | 3           | 2023-03-10  | 1      |
| 10        | 3           | 2023-06-10  | 2      |
| 11        | 3           | 2023-09-10  | 3      |
| 12        | 3           | 2023-12-10  | 4      |
| 13        | 4           | 2023-01-20  | 4      |
| 14        | 4           | 2023-04-20  | 4      |
| 15        | 4           | 2023-07-20  | 4      |
| 16        | 5           | 2023-02-15  | 3      |
| 17        | 5           | 2023-05-15  | 2      |
+-----------+-------------+-------------+--------+

Output:

+-------------+----------------+-------------------+
| employee_id | name           | improvement_score |
+-------------+----------------+-------------------+
| 2           | Bob Smith      | 3                 |
| 1           | Alice Johnson  | 2                 |
| 3           | Carol Davis    | 2                 |
+-------------+----------------+-------------------+

Explanation:

  • Alice Johnson (employee_id = 1):
    • Has 4 reviews with ratings: 2, 3, 4, 5
    • Last 3 reviews (by date): 2023-04-15 (3), 2023-07-15 (4), 2023-10-15 (5)
    • Ratings are strictly increasing: 3 → 4 → 5
    • Improvement score: 5 - 3 = 2
  • Carol Davis (employee_id = 3):
    • Has 4 reviews with ratings: 1, 2, 3, 4
    • Last 3 reviews (by date): 2023-06-10 (2), 2023-09-10 (3), 2023-12-10 (4)
    • Ratings are strictly increasing: 2 → 3 → 4
    • Improvement score: 4 - 2 = 2
  • Bob Smith (employee_id = 2):
    • Has 4 reviews with ratings: 3, 2, 4, 5
    • Last 3 reviews (by date): 2023-05-01 (2), 2023-08-01 (4), 2023-11-01 (5)
    • Ratings are strictly increasing: 2 → 4 → 5
    • Improvement score: 5 - 2 = 3
  • Employees not included:
    • David Wilson (employee_id = 4): Last 3 reviews are all 4 (no improvement)
    • Emma Brown (employee_id = 5): Only has 2 reviews (needs at least 3)

The output table is ordered by improvement_score in descending order, then by name in ascending order.

Approach overview

Problem Overview: Each employee has a history of review ratings. Return the employees whose three most recent ratings are strictly increasing, along with their improvement, which is the latest rating minus the oldest of those three. Sort by improvement descending, then by name ascending.

Approach 1: Correlated Subqueries (O(n^2) time, O(1) extra space)

For each review, use a correlated subquery to count how many reviews for the same employee are more recent. Keep only rows where that count is less than 3, then compare the three ratings in order. Each subquery scans the table again, so the cost grows quickly with row count. Use this approach to confirm the problem logic, but do not submit it as-is. Interviewers will flag the repeated table scans.

Approach 2: Window Functions with ROW_NUMBER (O(n log n) time, O(n) space)

Partition the table by employee_id and order each partition by review_date DESC with ROW_NUMBER(). Row 1 is the latest review, row 3 is the third latest. Filter to rn <= 3, then aggregate per employee using conditional MAX(CASE WHEN rn = 1 ...) expressions to pivot the three ratings into columns. Keep employees with exactly three reviews where the oldest rating is less than the middle, and the middle is less than the latest. The improvement is the latest rating minus the oldest. The sort cost dominates, which gives O(n log n). This is the pattern to learn: rank within a group, filter by rank, then pivot.

Recommended for interviews: Interviewers expect the window function approach. The correlated subquery version shows you understand the requirement, but the ROW_NUMBER pivot shows you can write set-based SQL that scales. Practice the same pattern on other database problems and on window function problems to make it automatic.

Solution

Thinking

We only care whether an employee’s last three ratings are strictly increasing; the score is last minus first. Number reviews per employee by date descending and shift to get adjacent deltas.

Keep ranks 2 and 3 (two deltas versus the latest review), require exactly two rows and a positive minimum delta, join names, and sort by score then name.

First, we extract the most recent three performance review records for each employee and calculate the difference in rating between each review and the previous one. Next, we filter out employees whose ratings are strictly increasing, and compute their improvement score (i.e., the last rating minus the first rating among the last three reviews). Finally, we sort the results by improvement score in descending order and by name in ascending order.

WITH
    recent AS (
        SELECT
            employee_id,
            review_date,
            ROW_NUMBER() OVER (
                PARTITION BY employee_id
                ORDER BY review_date DESC
            ) AS rn,
            (
                LAG(rating) OVER (
                    PARTITION BY employee_id
                    ORDER BY review_date DESC
                ) - rating
            ) AS delta
        FROM performance_reviews
    )
SELECT
    employee_id,
    name,
    SUM(delta) AS improvement_score
FROM
    recent
    JOIN employees USING (employee_id)
WHERE rn > 1 AND rn <= 3
GROUP BY 1
HAVING COUNT(*) = 2 AND MIN(delta) > 0
ORDER BY 3 DESC, 2;
import pandas as pd


def find_consistently_improving_employees(
    employees: pd.DataFrame, performance_reviews: pd.DataFrame
) -> pd.DataFrame:
    performance_reviews = performance_reviews.sort_values(
        ["employee_id", "review_date"], ascending=[True, False]
    )
    performance_reviews["rn"] = (
        performance_reviews.groupby("employee_id").cumcount() + 1
    )
    performance_reviews["lag_rating"] = performance_reviews.groupby("employee_id")[
        "rating"
    ].shift(1)
    performance_reviews["delta"] = (
        performance_reviews["lag_rating"] - performance_reviews["rating"]
    )
    recent = performance_reviews[
        (performance_reviews["rn"] > 1) & (performance_reviews["rn"] <= 3)
    ]
    improvement = (
        recent.groupby("employee_id")
        .agg(
            improvement_score=("delta", "sum"),
            count=("delta", "count"),
            min_delta=("delta", "min"),
        )
        .reset_index()
    )
    improvement = improvement[
        (improvement["count"] == 2) & (improvement["min_delta"] > 0)
    ]
    result = improvement.merge(employees[["employee_id", "name"]], on="employee_id")
    result = result.sort_values(
        by=["improvement_score", "name"], ascending=[False, True]
    )
    return result[["employee_id", "name", "improvement_score"]]
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Correlated SubqueriesO(n^2)O(1)Quick prototype or to verify logic on small data
Window Functions with ROW_NUMBERO(n log n)O(n)General case and interview answer

Frequently asked questions

Is Find Consistently Improving Employees easy or hard?

It is rated Medium with a 58.4% acceptance rate. The difficulty comes from combining ranking, filtering to the latest three rows, and checking strict ordering in one query. Once you know the ROW_NUMBER pattern, the implementation is short.

Find Consistently Improving Employees Python/Java solution

This problem is written in SQL, so there is no Python or Java answer on the platform. If you want the same logic in Python, use pandas: sort by review_date descending within each employee_id, take the first three rows per group, and check that the ratings strictly increase. The pandas version runs in O(n log n) time.

How to solve Find Consistently Improving Employees in O(n)?

A single pass in SQL is not possible here because the database must sort reviews by date within each employee. Treat O(n log n) as the practical bound. In application code, you could do one pass per employee after sorting, but that still requires sorting, so the bound stays O(n log n).

What is the best approach for Find Consistently Improving Employees?

The best approach uses window functions. Apply ROW_NUMBER() partitioned by employee_id and ordered by review_date descending, keep the three most recent reviews, pivot them into columns, and check that the ratings strictly increase. This runs in O(n log n) time with O(n) space.

Is Find Consistently Improving Employees asked at Google/Amazon/Meta?

This problem is tagged as a database question on LeetCode, and it is a common style of SQL interview question at large tech companies. Amazon, Meta, and Google interviews often test ROW_NUMBER, conditional aggregation, and filtering on window results, which this problem combines.

What data structure is used in Find Consistently Improving Employees?

The problem uses a relational table, not a traditional data structure. The key SQL tools are the ROW_NUMBER() window function for ranking reviews within each employee, and conditional aggregation with CASE WHEN to pivot ratings into columns for comparison.

What is the time complexity of Find Consistently Improving Employees?

The optimal window function solution runs in O(n log n) time, where n is the number of review rows, because the partitioned ordering dominates the cost. The naive correlated subquery approach runs in O(n^2) time because it rescans the table for each row.

Comments

Now write it yourselfClose this page and solve Find Consistently Improving Employees in the editor, without looking.
Practise Find Consistently Improving Employees