服务器 频道

在AS400/DB2中实现排名的一种方法

  【IT168 服务器学院】在DB2 for Unix/Linux/Windows中实现排名可以使用OLAP函数,非常方便,但对于AS400/DB2无法使用OLAP函数的情况下,我采用临时表对排名列进行分组的方法。方法也许不是最优的,希望大家拍砖。

  虽然方法针对AS400/DB2数据库,但由于没有400环境,我这里还是以自己机器上Windows/DB2作为测试环境。以下的SQL语法在AS400/DB2环境下一样可以使用。

   测试的表是sample数据库的表satff,为了更能突出排名后的结果,测试前我修改了一下这个表的数据。先备份表数据:

  >db2 export to staff.del of del select * from staff

  SQL3104N Export 实用程序开始将数据导出到文件 "staff.del" 中。

   SQL3105N Export 实用程序已导出 "35" 行。

   导出的行数:35

   将列salary整除至百位:

   >db2 update staff set salary = round(salary / 100,0) * 100

  DB20000I SQL 命令成功完成。

  为了生成序列,必须先在存储过程中建立一个带有标识列的临时表,并将staff表数据插入临时表。(在命令行内不能建临时表,我测试时用实表代替了。)

   declare temporary table tmp_rank(
     id      int not null generated always as identity (start with 1 increment by 1),
     name    varchar(9) ,
     salary  decimal(7,2)
     )with replace on commit delete rows not logged;

   insert into session.tmp_rank(name,salary) select name,salary from staff order by salary;(注意:插入时必须要排序)

  我这里把薪水的最低值排在最前了,如果要从高到低排名,只要在插入临时表时以薪水的倒序来排就可以了。

  原数据:

   >db2 select * from tmp_rank

  ID      NAME    SALARY
----------- --------- ---------
     1 Yamaguchi 10500.00
     2 Burke   11000.00
     3 Scoutten  11500.00
     4 Abrahams  12000.00
     5 Kermisch  12300.00
     6 Ngan      12500.00
     7 Naughton  13000.00
     8 Gafney    13000.00
     9 Lundquist 13400.00
     10 James     13500.00
     11 Sneider   14300.00
     12 Wheeler   14500.00
     13 Davis     15500.00
     14 Rothman   16500.00
     15 Quigley   16800.00
     16 Gonzales  16900.00
     17 Marenghi  17500.00
     18 Smith   17700.00
     19 Edwards   17800.00
     20 O''Brien   18000.00
     21 Koonitz  18000.00
     22 Pernal   18200.00
     23 Sanders  18400.00
     24 Plotz   18400.00
     25 Lea    18600.00
     26 Wilson   18700.00
     27 Daniels  19300.00
     28 Williams  19500.00
     29 Quill   19800.00
     30 Lu     20000.00
     31 Hanes   20700.00
     32 Graham   21000.00
     33 Fraye   21200.00
     34 Jones   21200.00
     35 Molinare  23000.00

  35 条记录已选择。

  
  最后用一条语句输出排名后的结果:

  >db2 select a.*,b.rank from tmp_rank a left outer join
  (select min(id) as rank,salary from tmp_rank group by salary) b
  on a.salary = b.salary

    ID      NAME    SALARY   RANK
  ----------- --------- --------- -----------
       1 Yamaguchi 10500.00  1
       2 Burke        11000.00  2
       3 Scoutten    11500.00  3
       4 Abrahams  12000.00  4
       5 Kermisch   12300.00  5
       6 Ngan         12500.00  6
       7 Naughton   13000.00  7
       8 Gafney      13000.00  7
       9 Lundquist   13400.00  9
       10 James      13500.00 10
       11 Sneider    14300.00 11
       12 Wheeler   14500.00 12
       13 Davis       15500.00 13
       14 Rothman  16500.00 14
       15 Quigley    16800.00 15
       16 Gonzales  16900.00 16
       17 Marenghi  17500.00 17
         18 Smith     17700.00 18
       19 Edwards   17800.00 19
       20 O''Brien    18000.00 20
       21 Koonitz    18000.00 20
       22 Pernal     18200.00 22
       23 Sanders  18400.00 23
       24 Plotz       18400.00 23
       25 Lea         18600.00 25
       26 Wilson     18700.00 26
       27 Daniels    19300.00 27
       28 Williams  19500.00 28
       29 Quill        19800.00 29
       30 Lu           20000.00 30
       31 Hanes      20700.00 31
       32 Graham   21000.00 32
       33 Fraye      21200.00 33
       34 Jones      21200.00 33
       35 Molinare  23000.00 35 
 
  35 条记录已选择。

0
相关文章