如何在oracle中为非null值分配排名

时间:2013-08-19 06:36:24

标签: sql oracle oracle11g

我需要以忽略空值的方式分配排名。

select root_cause_desc,
       case 
         when root_cause_desc is null 
         then null  
         else rank() over ( order by excess_value desc) 
       end gap_rank 
 from table.
where root_cause_desc is not null

给出

ROOT_CAUSE_DESC EXCESS_VALUE    TOTAL_EXCESS_VALUE_WK   GAP_RANK

advanced shipment   120.9750138     -760356.4054             10
dfdfdfdf222                0        -1696000.946             11
Root Cause         -0.0760554       -760356.4054             12
test one more      -656.277192      -760356.4054             13
earlier truck      -77099.35         720093.3712             14

它会忽略null值,并为null根本原因分配排名。我想gap_rank为1,2,3,4。现在请告诉我如何做到这一点。

2 个答案:

答案 0 :(得分:3)

问题在于RANK()与您的案例陈述无关;它通过您提供的ORDER BY子句对整个查询进行排序。

利用NULLS LAST关键字将NULL值放在订单的末尾,然后CASE语句就可以了。例如:

with the_data as (
 select level as a
      , nullif(nullif(level, 5), 8) as b
   from dual
 connect by level <= 10
         )
 select a
      , b
      , case when b is null then null
             else rank() over ( order by case when b is not null then 1
                                         end nulls last
                                        , a )
        end as "rank"
   from the_data
  order by a;

         A          B       rank
---------- ---------- ----------
         1          1          1
         2          2          2
         3          3          3
         4          4          4
         5
         6          6          5
         7          7          6
         8
         9          9          7
        10         10          8

10 rows selected.

SQL Fiddle

答案 1 :(得分:0)

我认为不需要在select子句中检查root_cause_desc is null。 where by,order by order by子句首先执行,然后处理分析函数。因此,在处理你的等级之前,它将消除null root_cause_desc。

WITH tab
     AS (SELECT NULL root_cause, 5 AS val FROM DUAL
         UNION ALL
         SELECT 'A' root_cause, 1 AS val FROM DUAL
         UNION ALL
        SELECT NULL root_cause, 4 AS val FROM DUAL
         UNION ALL
         SELECT 'A' root_cause, 2 AS val FROM DUAL
         UNION ALL
         SELECT NULL root_cause, 3 AS val FROM DUAL)
SELECT root_cause, val, RANK () OVER (ORDER   BY val DESC) rnk
  FROM tab
 WHERE root_cause IS NOT NULL;

root_casue   val     rnk
=========================

A           2          1
A           1          2
===========================