Reputation: 213
I am using oracle SQL developer 11g. I have a database of 100 football players. I have a table called PROFILE_PLAYERS which has following columns:
player_id, player_name, attack_skill(number),
defense_skill(number), passing_skill(number), GK_skill(number)
Now, I want to form a team of 11 players which contains 3 best attackers (highest attack_skill), 4 best midfielders (highest passing_skill), 3 best defenders (best defense_skill) and 1 best GK (best GK_skill).
I want to write a procedure which displays the 11 best players with their player_name and player_id.
Can I use the rank() here? Should I use for loop with a counter in the procedure?
Upvotes: 1
Views: 292
Reputation: 79033
If you ignore that the same player could be selected more than once due to different skills, the query could look like this:
select player_id, player_name
from (
select player_id, player_name,
rank() over(order by attack_skill desc) attack_rank,
rank() over(order by defense_skill desc) defense_rank,
rank() over(order by passing_skill desc) passing_rank,
rank() over(order by gk_skill desc) gk_rank
from profile_players
)
where attack_rank <= 3 or defense_rank <= 4
or passing_rank <= 3 or gk_rank <= 1;
To be sure that you get exactly 11 players, you have to apply a few tricks:
select player_id, player_name
from (
select player_id, player_name,
least((attack_rank - 1) / 3, (defense_rank - 1) / 4,
(passing_rank - 1) / 3, gk_rank - 1) blended_rank
from (
select player_id, player_name,
rank() over(order by attack_skill desc) attack_rank,
rank() over(order by defense_skill desc) defense_rank,
rank() over(order by passing_skill desc) passing_rank,
rank() over(order by gk_skill desc) gk_rank
from profile_players
)
order by blended_rank desc
)
where rownum <= 11;
You can then wrap this query into a stored procedure if you really need to have a procedure.
Upvotes: 1