Reputation: 31
I have this requirement of calculating a custom rank. I need to calculate Annualized % Return for all the 6 companies. I get rank from their return %. Let's consider this as input data. Now I need to calculate Custom Ranking where if another company's return is within a percentage point of Company A, I need to assign all these companies same rank (as shown in the chart below). I have 6 companies which is going to be fixed.
So, in a nutshell my requirement is to find which companies are within a percentage point return of company A. Then convert their rank to a string and concatenate their rank; keep the rest of the ranks the same and assign it to a new variable.
Attached Image is for illustration only.
Upvotes: 0
Views: 108
Reputation: 24783
The trick is to find the dense_rank()
based on the absolute value of Difference from A
. For difference less than 1.0%
, it is treat as 0
.
-- Sample Table
declare @company table
(
Company char,
AnnualReturns decimal(5,1)
)
-- Sample Data
insert into @company
values ('A', 5.5), ('B', 7.7), ('C', -1.3), ('D', 6.3), ('E', 5.4), ('F', 9.0)
-- The query
; with cte as
(
select *,
[Difference from A] = AnnualReturns - 5.5,
ActualRank = row_number() over (order by AnnualReturns desc),
dr = dense_rank() over (order by case when abs(AnnualReturns - 5.5) <= 1.0
then 0
else abs(AnnualReturns - 5.5)
end)
from @company
)
select Company, AnnualReturns, [Difference from A], ActualRank,
stuff(RequiredRank, 1, 1, '') as RequiredRank
from cte c
cross apply -- concatenate the rank
(
select '/' + convert(varchar(10), ActualRank)
from cte x
where x.dr = c.dr
order by ActualRank
for xml path('')
) rr (RequiredRank)
order by Company
Upvotes: 2