SQL - 基于单独列中的分数排名

时间:2018-02-07 17:51:03

标签: sql sybase sybase-iq

我有下表:

userID|Exam1|Exam2|Exam3|
johnd    10    3      5

我想对得分进行排名,并将排名放入新列中,如下所示:

userID|Exam1|Exam2|Exam3|Rank1|Rank2|Rank3
johnd   10     3     5   Exam1 Exam3 Exam2

我正在使用Sybase IQ。

提前致谢

2 个答案:

答案 0 :(得分:1)

Greg的答案适用于三门考试。它并不是很普遍。另一种方法是进行聚合:

xp_cmdshell

这可以更轻松地推广到更多考试 - 只需在最里面的查询中添加另一个select t.userid, t.exam1, t.exam2, t.exam3, max(case when seqnum = 1 then examname end) as rank1, max(case when seqnum = 2 then examname end) as rank2, max(case when seqnum = 3 then examname end) as rank3 from (select t.*, row_number() over (partition by userid order by exam desc) as seqnum from ((select t.*, exam1 as exam, 'exam1' as examname from t) union all (select t.*, exam2 as exam, 'exam2' as examname from t) union all (select t.*, exam3 as exam, 'exam3' as examname from t) ) t ) t group by t.userid, t.exam1, t.exam2, t.exam3; ,在最外层查询中添加另一个union all

答案 1 :(得分:0)

由于您无法在Sybase中使用UNPIVOT,因此您将被迫使用一组精心设计的CASE语句来执行此操作。

SELECT Exam_Sort.UserID, Exam_Sort.Exam1, Exam_Sort.Exam2, Exam_Sort.Exam3
, 'Exam' & SUBSTRING(Exam_Sort.ExamOrder,1,1) AS Rank1
, 'Exam' & SUBSTRING(Exam_Sort.ExamOrder,2,1) AS Rank2
, 'Exam' & SUBSTRING(Exam_Sort.ExamOrder,3,1) AS Rank3
FROM
(SELECT table.UserID, table.Exam1, table.Exam2, table.Exam3
, CASE WHEN table.Exam1 >= table.Exam2 THEN
       CASE WHEN table.Exam2 >= table.Exam3 THEN '123'
            ELSE CASE WHEN table.Exam1 >= table.Exam3 THEN '132' ELSE '312' END END
  ELSE CASE WHEN table.Exam2 < table.Exam3 THEN '321'
            ELSE CASE WHEN table.Exam1 >= table.Exam3 THEN '213' ELSE '231' END END
END as [ExamOrder]
FROM table) as Exam_Sort