I have input table as shown below -
ID Name q1 q2 q3 q4
1 a 2621 2036 1890 2300
2 b 18000 13000 14000 15000
3 c 100 200 300 400
I want ranking of columns(q1, q2, q3 and q4
) data for each row. For example, if I consider last row of above input, then q4
column contains 400
value which is higher than other columns, so rank to q4
column will be 1
, q3
rank will be 2
, q2
rank will be 3
and q1
rank will be 4
.
I am looking for output like -
id name q1 q2 q3 q4
1 a 1 3 4 2
2 b 1 4 3 2
3 c 4 3 2 1
There are more than 100,000 records present in input table.
I have created small SQL script for input table i.e.,
declare @temp table (ID int, Name varchar(10), q1 int, q2 int, q3 int, q4 int)
insert into @temp
select 1, 'a', 2621, 2036, 1890, 2300
union all
select 2, 'b', 18000, 13000, 14000, 15000
union all
select 3, 'c', 100, 200, 300, 400
select * from @temp
Please help me to find efficient way to solve this problem.
Rank on two columns Select a blank cell which you will place the ranking result, for instance, D2, and type this formula =RANK(B2,$B$2:$B$7)+SUMPRODUCT(--($B$2:$B$7=$B2),--(C2<$C$2:$C$7)), press Enter key, and then drag fill handle over the cells which use this formula.
If you want to create a ranking based on a different column or in a different order (i.e., ascending instead of descending), simply change the column name or change the DESC keyword to the ASC keyword.
The row_number gives continuous numbers, while rank and dense_rank give the same rank for duplicates, but the next number in rank is as per continuous order so you will see a jump but in dense_rank doesn't have any gap in rankings.
Unlike DENSE_RANK , RANK skips positions after equal rankings. The number of positions skipped depends on how many rows had an identical ranking. For example, Mary and Lisa sold the same number of products and are both ranked as #2. With RANK , the next position is #4; with DENSE_RANK , the next position is #3.
You need UNPIVOT
& PIVOT
:
SELECT Id, Name,
MAX(CASE WHEN qname = 'q1' THEN SEQ END),
MAX(CASE WHEN qname = 'q2' THEN SEQ END),
MAX(CASE WHEN qname = 'q3 'THEN SEQ END),
MAX(CASE WHEN qname = 'q4 'THEN SEQ END)
FROM (SELECT t.*, tt.*,
DENSE_RANK() OVER (PARTITION BY t.Name ORDER BY tt.qq DESC) AS SEQ
FROM @temp t CROSS APPLY
( VALUES (q1, 'q1'), (q2, 'q2'), (q3, 'q3'), (q4, 'q4')
) tt(qq, qname)
) t
GROUP BY t.Id, t.Name;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With