2016-09-28 39 views
2

说我有如下表:如何在DENSE_RANK()中不计数NULL值?

col 
NULL 
1 
1 
2 

然后我选择:

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

然后我得到:

col rnk 
NULL 1 
1 2 
1 2 
2 3 

我想是这样的:

col rnk 
NULL NULL 
1 1 
1 1 
2 2 

但是如果我q uery:

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

然后我得到:

col rnk 
NULL NULL 
1 2 
1 2 
2 3 

有没有办法忽略NULL的排名时,除使用WHERE条款等?我有一些其他列的行不能省略。

+0

BQ或Teradata的?他们是非常不同的。正确标记! –

+0

BQ现在支持标准SQL。 – cshin9

+0

“standard SQL”<>“Teradata SQL” –

回答

4

使用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; 
+1

只是为了澄清 - 此答案适用于BigQuery Standard SQL –

+0

@MikhailBerlyant。 。 。就我所知,这个查询可以在任何支持'dense_rank()'的SQL引擎中工作。 –

+0

但与BigQuery Legacy SQL不兼容:o)由于传统SQL中的PARTITION BY只允许字段名称,而不允许使用表达式 –

0

下面是BigQuery的传统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 
)