如何在没有OLAP功能的情况下获得常规排名

时间:2013-11-18 02:35:24

标签: sql db2

我想做没有OLAP功能的常规排名行(没有RANK()或类似的那样)。我想创建一个具有短期平均响应时间的用户的“前10名”列表。我在下面得到了这个问题:

    WITH table_avg (NICKNAME, AVG_RESPONSETIME) AS
  (SELECT r.nickname,
          AVG ((timestampdiff(32,char(timestamp(e1.date) -timestamp(e2.date)))))AS AVG_RESPONSETIME
   FROM email e1, 
        email e2, 
        address a,
        use u,
        user r
   WHERE e2.id=e1.in_reply_to
     AND e1.from=a.id
     AND a.id=u.address
     AND u.user=r.id
   GROUP BY r.nickname HAVING count(r.nickname)>=3
   ORDER BY 1 ASC,2 ASC)

SELECT a.NICKNAME,
       a.AVG_RESPONSETIME,
       count(DISTINCT b.AVG_RESPONSETIME) AS RANK
FROM table_avg a,
     table_avg b
WHERE b.AVG_RESPONSETIME<=a.AVG_RESPONSETIME
GROUP BY a.NICKNAME,
         a.AVG_RESPONSETIME HAVING count(DISTINCT b.AVG_RESPONSETIME) <=10
ORDER BY RANK ASC,
         a.NICKNAME ASC

结果是:

NICKNAME    AVG_RESPONSETIME RANK
 ----------- ---------------- ----
 cyber426                   1    1
 neo927                     1    1
 neo259                     3    2
 cypher15                   4    3
 fool28                     5    4
 cyber974                   6    5
 hacker285                  6    5
 dau719                     7    6
 trinity407                 7    6
 fool380                    8    7
 wiesel509                  8    7
 dau814                    10    8
 morpheus462               10    8
 neo517                    10    8
 drago831                  11    9
 drago861                  13   10

如何让排名跳过数字2?它应该是3号,我想要的结果是:

NICKNAME    AVG_RESPONSETIME    RANK
---------- ------------------- -----
cyber426                   1    1
neo927                     1    1
neo259                     3    3
cypher15                   4    4
fool28                     5    5
cyber974                   6    6
hacker285                  6    6
dau719                     7    8
trinity407                 7    8
fool380                    8    10
wiesel509                  8    10

我不能使用RANK功能,这是我应该做的练习。

提前致谢!!!

1 个答案:

答案 0 :(得分:0)

我找到了一种复杂的方法,可以用标准的select语句做你想做的事情。你仍然需要找出它的工作原理(我知道为什么)。我没有给你解释,所以你需要考虑它并有机会学习。一个更简单的选择是使用游标。

SELECT a.NICKNAME,
  a.AVG_RESPONSETIME,
  count(b.AVG_RESPONSETIME) + 1 - count(case (a.AVG_RESPONSETIME - b.AVG_RESPONSETIME) when 0 then 1 else NULL end) as rank
FROM table_avg a, table_avg b
WHERE b.AVG_RESPONSETIME<=a.AVG_RESPONSETIME
GROUP BY a.NICKNAME, a.AVG_RESPONSETIME HAVING count(b.AVG_RESPONSETIME) <=10
ORDER BY RANK ASC, a.NICKNAME ASC;

使用ideone.com进行测试 - http://ideone.com/9F4gFo