I am on MS-SQL 2016.
I have a scenario that requires to get top 2 paid bonus for each group, RANK and ROW_NUMBER are not allowed, here is the code you can use to generate the table and data:
Create table Freelancer (id int, fl_name varchar(20), bonus int, fl_group varchar(50))
insert into Freelancer (id, fl_name, bonus, fl_group) Values (1, 'John', 1000, 'SQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (2, 'Jane', 990, 'MySQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (3, 'Jimmy', 320, 'Oracle')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (4, 'Jeff', 802, 'DynamoDB')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (5, 'Johnathan', 2345, 'Hive')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (6, 'Jeffery', 321, 'RDS')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (7, 'Jane2', 1990, 'MySQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (8, 'Jimmy3', 321, 'Oracle')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (9, 'Jeff4', 803, 'DynamoDB')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (10, 'Johnathan5', 345, 'Hive')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (11, 'Jeffery', 32, 'RDS')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (12, 'Jane3', 1190, 'MySQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (13, 'Jimmy4', 322, 'Oracle')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (14, 'Jeff5', 8002, 'DynamoDB')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (15, 'Johnathan6', 235, 'Hive')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (16, 'Jeffery7', 31, 'RDS')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (17, 'Jack', 34, 'Redshift')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (18, 'Jennifer', 121, 'Aurora')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (19, 'Jackson', 425, 'Redis')
The expected result is for example in group DynamoDB, Jeff5(8002) and Jeff4(803) would be picked up
What I tried already is below and not returning the needed result despite I specified top 2 in the clause:
select *
from Freelancer t
where t.ID in (
select top 2 ID
from Freelancer tt
where tt.fl_name = t.fl_name
order by tt.bonus desc
)
order by fl_group, bonus desc
my result:
5
Answers
You should be comparing bonuses between the outer query and subquery, and you should be correlating using the group.
If you can use other windowed functions, try to replace
ROW_NUMBER()
behaviour with windowedSUM()
:Use a correlated subquery which returns for each row the number of rows having greater bonus in that group:
See the demo.
Results:
You can use
APPLY
:Please try this solution, hear in this solution I have consolidated fl_group as your category, and get fl_group wise top 2 records.
Declare temp table
Insert Sample data
Category-wise Top 2 Records
Output
Here, you can also use join instead of the subquery to improve your query performance.
For More information, you can try this solution Please Visit this URL: Query Editor
I hope this works for you.