创建一个具有NULL值/ 0的数组,并查找不包含null / 0的数组长度

时间:2019-01-07 02:17:10

标签: sql arrays google-bigquery

我想查找每行中具有非null和> 0值的范围内的列数。

我目前使用case when语句或IF-ELSE完成了此操作。但是我现在必须考虑的列数增加了,并且case语句的数目也增加了。

所以我想创建列的array,然后在排除length0值之后找到数组的NULL

我尝试了以下代码,但出现错误

**case1**
SELECT [col1,col2,col3,col4,col5] from input_Table

Error: Array cannot have a null element; error in writing field

**case2**
SELECT *,
  ARRAY(SELECT col1,col2,col3,col4,col5
        from input_table
        WHERE col1 is not null and col2 is not null ...) 
from input_Table

Error: ARRAY subquery cannot have more than one column unless using SELECT AS STRUCT to build STRUCT values at [2:3]

下面是我的数据快照 enter image description here

我想要的输出是

1
2
0

如果有人可以帮助我,那将非常有帮助,我对Bigquery还是很陌生。

2 个答案:

答案 0 :(得分:2)

一种方法是仅使用case -因为您知道列数:

select id,
       (case when col1 = 0 or col1 is null then 0
             when col2 = 0 or col2 is null then 1
             when col3 = 0 or col3 is null then 2
             when col4 = 0 or col4 is null then 3
             when col5 = 0 or col5 is null then 4
             else 5
        end) as result             
from t;

尽管可以对数组进行奇特的操作,但鉴于列数是有限的并且case表达式非常简单,因此我认为不需要这样做。

答案 1 :(得分:2)

  

我想查找每行中具有非null和> 0值的范围内的列数...

选项1

以下内容适用于BigQuery,并且通用性足以适用于任意数量的列

SELECT *,
  (SELECT COUNT(1) 
    FROM UNNEST(REGEXP_EXTRACT_ALL(
        TO_JSON_STRING(t), r'"col\d+":(.*?)[,}]')     
      ) value
    WHERE NOT value IN ('null', '0')
  ) AS non_null_0_count
FROM `project.dataset.table` t

以上假设列的模式为col1,col2,..,colNN

您可以使用下面的问题中的虚拟数据来测试,并在上面玩

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 id, 1 col1, 0 col2, 0 col3, 0 col4, 0 col5 UNION ALL
  SELECT 2, 4, 5, 0, 0, 0 UNION ALL
  SELECT 3, NULL, NULL, NULL, NULL, NULL
)
SELECT *,
  (SELECT COUNT(1) 
    FROM UNNEST(REGEXP_EXTRACT_ALL(
        TO_JSON_STRING(t), r'"col\d+":(.*?)[,}]')     
      ) value
    WHERE NOT value IN ('null', '0')
  ) AS non_null_0_count
FROM `project.dataset.table` t

有结果

Row id  col1    col2    col3    col4    col5    non_null_0_count     
1   1   1       0       0       0       0       1    
2   2   4       5       0       0       0       2    
3   3   null    null    null    null    null    0      

选项2

如果上述列模式不是真正的情况-这种方法仍然有效-请参见下面的示例-您只需要在regexp中枚举那些列

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 id, 1 abc, 0 xyz, 0 qwe, 0 asd, 0 zxc UNION ALL
  SELECT 2, 4, 5, 0, 0, 0 UNION ALL
  SELECT 3, NULL, NULL, NULL, NULL, NULL
)
SELECT *,
  (SELECT COUNT(1) 
    FROM UNNEST(REGEXP_EXTRACT_ALL(
        TO_JSON_STRING(t), r'"(?:abc|xyz|qwe|asd|zxc)":(.*?)[,}]')
      ) value
    WHERE NOT value IN ('null', '0') 
  ) AS non_null_0_count
FROM `project.dataset.table` t

结果为

Row id  abc     xyz     qwe     asd     zxc     non_null_0_count     
1   1   1       0       0       0       0       1    
2   2   4       5       0       0       0       2    
3   3   null    null    null    null    null    0      

选项3

显然,最简单直接的选择是

#standardSQL
SELECT *, 
  (
    SELECT COUNT(1)
    FROM (
      SELECT col1 col UNION ALL 
      SELECT col2 UNION ALL 
      SELECT col3 UNION ALL 
      SELECT col4 UNION ALL 
      SELECT col5
    )
    WHERE NOT col IS NULL AND col != 0
  ) AS non_null_0_count
FROM `project.dataset.table` t