4

Say I have the following table:

col
NULL
1
1
2

Then I select:

SELECT col, DENSE_RANK() OVER(ORDER BY col) as rnk from table

Then I get:

col  rnk
NULL 1
1    2
1    2
2    3

What I want to get is this:

col  rnk
NULL NULL
1    1
1    1
2    2

But if I query:

SELECT col, CASE WHEN col IS NOT NULL THEN DENSE_RANK() OVER(ORDER BY col) END as rnk from table

Then I get:

col  rnk
NULL NULL
1    2
1    2
2    3

Is there a way to disregard NULLs when ranking, other than using a WHERE clause? I have some other columns whose rows cannot be omitted.

cshin9
  • 1,440
  • 5
  • 20
  • 33

3 Answers3

6

Use partition by:

SELECT col,
       (CASE WHEN col IS NOT NULL
             THEN DENSE_RANK() OVER (PARTITION BY (CASE WHEN col IS NOT NULL THEN 1 ELSE 2 END)
                                     ORDER BY col
                                    )
        END) as rnk
FROM table;
Mikhail Berlyant
  • 165,386
  • 8
  • 154
  • 230
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

Below is for BigQuery Legacy SQL

SELECT col, CASE WHEN col IS NOT NULL THEN rnk END AS rnk
FROM (
  SELECT 
    col, (col IS NULL) AS tmp, 
    DENSE_RANK() OVER(PARTITION BY tmp ORDER BY col) AS rnk 
  FROM table
)
Mikhail Berlyant
  • 165,386
  • 8
  • 154
  • 230
0
select 
col,
case 
   when col is not null -- to override dense_rank 3 to NULL for the NULL record
   then dense_rank() over (order by col nulls last)
   end as rnk
from table 
order by col asc
;

gives result

       COL        RNK
---------- ----------
                     
         1          1
         1          1
         2          2
Shankar S
  • 91
  • 4