首页 > 解决方案 > 如何在Oracle SQL中对同一行的列进行排名

问题描述

我在表中有以下行:

C1 |C2 |C3 |C4

 7 | 3 | 1 | 6

我想以这样一种方式构造一个查询,即给每一列一个顺序;

O1 |O2 |O3 |O4
 4 | 2 | 1 | 3

是否可以在单个查询中进行这种逐行比较?或者是构造复杂case when语句的唯一选择?

编辑:我试图绕过的情况:

case 
    when C1 = greatest ( C1, C2, C3, C4) then 1
    when C1 >= C2 and C1 >= C3 and C1 < C4
      or C1 >= C2 and C1 <  C3 and C1 >= C4
      or C1 <  C2 and C1 >= C3 and C1 >= C4 then 2
    when C1 >= C2 and C1 <  C3 and C1 <  C4
      or C1 <  C2 and C1 >= C3 and C1 <  C4
      or C1 <  C2 and C1 <  C3 and C1 >= C4 then 3
    when C1 = least (C1, C2, C3, C4 ) then 4 
end as O1

如果值相等,则索引确定顺序:如果 C2 = C3,O2 = 1,O2 = 3。

如您所见,这很容易出错。有没有办法让这种比较更优雅?

比较只需要在单行中进行,单行中列的顺序不会影响表中行的顺序。

编辑 2:表中有多行,用 ID_ROW 标识。

标签: sqloraclesql-order-by

解决方案


复杂的嵌套 case-when 不是必需的,您可以使用“simple” case-when 和 sum(虽然有点乏味)

select t.*,

     case when c1>c2 then 1 else 0 end
     + case when c1>c3 then 1 else 0 end
     + case when c1>c4 then 1 else 0 end + 1 as q1,

     case when c2>c1 then 1 else 0 end
     + case when c2>c3 then 1 else 0 end
     + case when c2>c4 then 1 else 0 end + 1 as q2,

     case when c3>c1 then 1 else 0 end
     + case when c3>c2 then 1 else 0 end
     + case when c3>c4 then 1 else 0 end + 1 as q3 ,

     case when c4>c1 then 1 else 0 end
     + case when c4>c2 then 1 else 0 end
     + case when c4>c3 then 1 else 0 end + 1 as q4 

FROM table1 t;

| c1 | c2 | c3 | c4 | q1 | q2 | q3 | q4 |
|----|----|----|----|----|----|----|----|
|  7 |  3 |  1 |  6 |  4 |  2 |  1 |  3 |
|  6 |  5 |  4 |  1 |  4 |  3 |  2 |  1 |

推荐阅读