【问题标题】:How can I rank sequential rows with a null value in a query?如何在查询中对具有空值的连续行进行排名?
【发布时间】:2012-03-30 00:14:39
【问题描述】:

我想在一组相同的自然键中对具有空值的连续行进行排名。数据库是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()函数,level和connect by或其他方法。

【问题讨论】:

标签: sql database oracle11g


【解决方案1】:

我的猜测是你想要类似的东西

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

【讨论】:

  • 如果您尝试使用完整的示例,您会发现它不起作用。还是谢谢。
【解决方案2】:

我终于通过 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

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多