【问题标题】:Using ARRAY_AGG() with all null values in input将 ARRAY_AGG() 与输入中的所有空值一起使用
【发布时间】:2016-10-04 05:57:07
【问题描述】:

我想为我的表(在 Google BigQuery 中)中的每个用户选择不同的列值。我考虑过使用ARRAY_AGG(),比如:

SELECT user_id, ARRAY_AGG(DISTINCT field1) AS f1, ARRAY_AGG(DISTINCT field2) AS f2
FROM t GROUP BY user_id

但是因为对于某些 user_ids,field1field2 中的所有值都为空,我收到此错误消息:Array 'f1' cannot have a null element

我想知道是否有一种解决方法可以避免此错误,或者是否有其他方法可以在不使用 ARRAY_AGG() 的情况下获得结果

【问题讨论】:

标签: sql google-bigquery


【解决方案1】:

来自https://cloud.google.com/bigquery/sql-reference/data-types#array-type

如果查询结果的 ARRAY 包含 NULL,BigQuery 会引发错误 元素,尽管这样的 ARRAY 可以在查询中使用。

您的查询在临时查询中正常,但在最终查询结果中不正常;所以解决方法是您可以将查询定义为 tmp 表并在给出最终结果之前过滤掉 NULL 值:

WITH tmp AS (SELECT user_id,
                    ARRAY_AGG(DISTINCT field1) AS f1,
                    ARRAY_AGG(DISTINCT field2) AS f2
FROM t GROUP BY user_id)

SELECT user_id,
    ARRAY(SELECT el FROM UNNEST(f1) AS el WHERE el IS NOT NULL) AS f1,
    ARRAY(SELECT el FROM UNNEST(f2) AS el WHERE el IS NOT NULL) AS f2
 FROM tmp

我在将一些 Postgres SQL 移植到 BigQuery 时遇到了同样的问题,一个更优雅的解决方案是聚合函数上的 FILTER 子句,

https://www.postgresql.org/docs/current/static/sql-expressions.html

就像 ARRAY_AGG(f1 FILTER WHEN f1 IS NOT NULL) 在 BigQuery 中不可用,我真的希望他们能够实现它

【讨论】:

【解决方案2】:

BigQuery 终于从 Elliott Brossard 实现了 suggestion,现在您可以这样做了:

SELECT user_id, ARRAY_AGG(DISTINCT field1 IGNORE NULLS) AS f1, ARRAY_AGG(DISTINCT field2 IGNORE NULLS) AS f2
FROM t
GROUP BY user_id

【讨论】:

    【解决方案3】:
    WITH t1 AS (
      SELECT user_id, ARRAY_AGG(DISTINCT field1) AS f1
      FROM t WHERE field1 IS NOT NULL
      GROUP BY user_id
    ),
    t2 AS (
      SELECT user_id, ARRAY_AGG(DISTINCT field2) AS f2
      FROM t WHERE field2 IS NOT NULL
      GROUP BY user_id
    )
    SELECT t1.user_id, f1, f2
    FROM t1 FULL JOIN t2 
    ON t1.user_id = t2.user_id
    

    【讨论】:

      【解决方案4】:

      当您使用 ARRAY_AGG() 遇到空值时,请指定 IGNORE NULLS:

      IGNORE NULLS 或 RESPECT NULLS:如果指定了 IGNORE NULLS,则 NULL 值从结果中排除。如果 RESPECT NULLS 或者两者都不是 指定时,NULL 值将包含在结果中。一个错误是 如果最终查询结果中的数组包含 NULL 元素,则引发。

      发件人:https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#array_agg

      使用 IGNORE NULLS 的工作示例:

      SELECT
          category, 
          array_agg(fruit IGNORE NULLS) as fruits_array,
      FROM (SELECT "A" as category, NULL as fruit UNION ALL
            SELECT "B" as category, "apple" as fruit UNION ALL
            SELECT "B" as category, "pear" as fruit UNION ALL
            SELECT "C" as category, "orange" as fruit)
      GROUP BY category
      ORDER BY category
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-16
        • 1970-01-01
        相关资源
        最近更新 更多