如何在SQL Server中对多列数据进行排名?

12

我有一个输入表格,如下所示 -

ID  Name q1     q2      q3      q4
1   a    2621   2036    1890    2300
2   b    18000  13000   14000   15000
3   c    100    200     300     400
我想要每行中列(q1、q2、q3和q4)数据的排名。例如,如果我考虑上述输入的最后一行,则q4列包含400值,比其他列都高,因此q4列的排名将是1q3的排名将是2q2 的排名将是3q1 的排名将是4

我想要的输出如下 -

id  name  q1  q2  q3  q4
1   a     1   3   4   2
2   b     1   4   3   2
3   c     4   3   2   1

输入表中有超过10万条记录。

我已经为输入表创建了一个小的 SQL 脚本,即:

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
请帮我找到解决这个问题的高效方法。

请帮我找到解决这个问题的高效方法。


1
你尝试过任何方法吗? - Prashant Pimpale
你尝试过使用排名函数吗?排名函数 - ta.speot.is
1
看起来你想按行而不是按列进行排名。你可能需要进行数据透视、排序和逆向数据透视。 - HoneyBadger
1
似乎你正在尝试获取行中不同列的排名,而不是在一个特定列内;聚合函数在列级别上工作,而不是行级别(这也是为什么你应该保持数据规范化的另一个原因)。你需要对数据进行透视,以使其规范化,然后再将其逆转。 - Thom A
抢先一步了 @HoneyBadger :) - Thom A
@Larnu,你改变了惯常的做法,通常你都是第一个回答我心中所想的问题。 - HoneyBadger
1个回答

9
你需要使用 UNPIVOTPIVOT
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;

1
谢谢@Yogesh。你真的很快地解决了它。 - DatabaseCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接