【问题标题】:Create an array with NULL values/0 and find array length excluding null/0创建一个具有 NULL 值/0 的数组并查找不包括 null/0 的数组长度
【发布时间】:2019-06-01 17:33:53
【问题描述】:

我想在每一行的一个范围内找到非空且>0值的列数。

我目前使用case when 语句或IF-ELSE 完成了这项工作。但是我现在必须考虑的列数增加了,case 语句的数量也随之增加。

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

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

**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]

以下是我的数据快照

我想要的输出是

1
2
0

如果有人能帮我解决这个问题会非常有帮助,我是 Bigquery 的新手。

【问题讨论】:

    标签: sql arrays google-bigquery


    【解决方案1】:

    我想在每一行中找到一个范围内的列数,它具有非空和 >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

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

    #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
    

    【讨论】:

      【解决方案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 表达式非常简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-23
        • 1970-01-01
        • 2019-08-12
        • 2017-08-27
        • 1970-01-01
        • 2019-06-01
        • 1970-01-01
        相关资源
        最近更新 更多