You can use OUTER APPLY with TOP 2:
SELECT DISTINCT
y.[user_id],
d.salary,
d.[month]
FROM YourTable y
OUTER APPLY(
SELECT TOP 2 *
FROM YourTable
WHERE y.[user_id] = [user_id]
ORDER BY [user_id], salary DESC
) as d
ORDER BY [user_id], salary DESC
Will return:
user_id salary month
1 200 3
1 180 4
2 45 5
2 40 2
Another way:
;WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [user_id] ORDER BY salary DESC) as rn
FROM YourTable
)
SELECT [user_id], salary, [month]
FROM cte
WHERE rn <= 2
The same way out.
gofr1 source
share