如何在查询中使用空值对连续行进行排名?

时间:2012-03-30 00:14:39

标签: sql database oracle11g

我想在一组相同的自然键中对具有空值的连续行进行排名。数据库是oracle。

以下是示例:

NAT_KEY      ATTRIBUTE_A        ORDERED_FIELD               RANK
     A                A                     1
     A                                      2                  1
     A                A                     4
     A                I                     6
     A                                      8                  1
     A                                      10                 2
     A                                      11                 3
     B                                      2                  1
     B                                      3                  2
     B                A                     5
     B                A                     6
     B                                      9                  1
     C                A                     1
     C                A                     5
     C                I                     6
     C                                      7                  1
     C                                      8                  2

row_number()函数,levelconnect by或其他函数必须有办法。

2 个答案:

答案 0 :(得分:0)

我的猜测是你需要像

这样的东西
select key,
       attr,
       order_by,
       (case when rnk1 is not null
             then rank() over (partition by key order by rnk1)
             else null
         end) rnk
  from (
    select x.*,
           (case when attr is null
                 then row_number() over (partition by key order by order_by)
                 else null
             end) rnk1
      from <<table name>> x
  )
 order by key, order_by

产生这样的输出

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 'A' key, 'A' attr, 1 order_by from dual union all
  3    select 'A', null, 2 from dual union all
  4    select 'A', 'A', 4 from dual
  5  )
  6  select key,
  7         attr,
  8         order_by,
  9         (case when rnk1 is not null
 10               then rank() over (partition by key order by rnk1)
 11               else null
 12           end) rnk
 13    from (
 14      select x.*,
 15             (case when attr is null
 16                   then row_number() over (partition by key order by order_by)
 17                   else null
 18               end) rnk1
 19        from x
 20    )
 21*  order by key, order_by
SQL> /

K A   ORDER_BY        RNK
- - ---------- ----------
A A          1
A            2          1
A A          4

答案 1 :(得分:0)

我终于用Andriy M的链接想出来了。 这是解决方案:

select grouped_table.nat_key, 
       grouped_table.attr, 
       grouped_table.order_by,  
       case 
         when attr is null 
           then row_number() over (partition by nat_key, attr, grp order by order_by) 
         else null
       end rowrank 
from (
  select the_table.*, 
         row_number() over (partition by nat_key order by order_by) - row_number() over (partition by nat_key, nvl2(attr, 1, 0) order by order_by) grp 
  from (
    select 'A' nat_key, 'A' attr, 1 order_by from dual 
    union all 
    select 'A' nat_key, null attr, 2 order_by from dual 
    union all 
    select 'A' nat_key, 'A' attr, 4 order_by from dual 
    union all 
    select 'A' nat_key, 'I' attr, 6 order_by from dual 
    union all 
    select 'A' nat_key, null attr, 8 order_by from dual 
    union all 
    select 'A' nat_key, null attr, 10 order_by from dual 
    union all 
    select 'A' nat_key, null attr, 11 order_by from dual 
    union all 
    select 'B' nat_key, null attr, 2 order_by from dual 
    union all 
    select 'B' nat_key, null attr, 3 order_by from dual 
    union all 
    select 'B' nat_key, 'A' attr, 5 order_by from dual 
    union all 
    select 'B' nat_key, 'A' attr, 6 order_by from dual 
    union all 
    select 'B' nat_key, null attr, 9 order_by from dual 
    union all 
    select 'C' nat_key, 'A' attr, 1 order_by from dual 
    union all 
    select 'C' nat_key, 'A' attr, 5 order_by from dual 
    union all 
    select 'C' nat_key, 'I' attr, 6 order_by from dual 
    union all 
    select 'C' nat_key, null attr, 7 order_by from dual 
    union all 
    select 'C' nat_key, null attr, 8 order_by from dual 
  ) the_table 
) grouped_table 
order by nat_key, order_by

谢谢!