【问题标题】:How to combine multiple rows as one in Bigquery?如何在 Bigquery 中将多行合并为一个?
【发布时间】:2021-11-15 18:27:28
【问题描述】:

我有一个 BigQuery 表,其中的数据如下图所示

我希望从这些数据中创建一个表格,如下图所示

所以我想在这里

  1. 删除电子邮件列数据
  2. 将 emp_type 列值组合为逗号分隔值
  3. 每个 id 只有 1 行

我尝试使用 BigQuery 的 STRING_AGG 函数,但无法实现我上面指定的功能。

该表实际上有 30 多列,但为了解释问题,我将其减少到 7 列。

如何在一个查询中将多行合并为一个?

【问题讨论】:

    标签: sql google-cloud-platform google-bigquery


    【解决方案1】:

    考虑以下方法

    select 
      any_value((select as struct * except(email, emp_type) from unnest([t]))).*,
      string_agg(emp_type, ', ') emp_type
    from data t
    group by to_json_string((select as struct * except(email, emp_type) from unnest([t])))
    

    如果应用于您问题中的样本数据 - 输出是

    正如您在此处看到的 - 无论您有多少列 30+ 或 100+ ,它都会起作用。你甚至需要输入它们!

    【讨论】:

    • 如何消除作为 string_agg(emp_type, ', ') emp_type 一部分出现的重复条目? @MikhailBerlyant
    • 除非您在 string_agg 中包含 order by - 您可以在 string_agg 中使用 distinct - 请参阅文档了解详细信息
    【解决方案2】:

    我看到了两个可能的选项,如果您希望除 email 和 emp_type 之外的所有参数组合都有唯一的行:

    SELECT id, name, status, `count`, is_hybrid, STRING_AGG(emp_type, ', ')
    FROM data
    GROUP BY id, name, status, `count`, is_hybrid
    

    如果您只想每个 id 有一行,您可以按 id 分组并为其他列选择任意值(从具有此 id 的行中):

    SELECT id, ANY_VALUE(name), ANY_VALUE(status), ANY_VALUE(`count`), ANY_VALUE(is_hybrid), STRING_AGG(emp_type, ', ')
    FROM data
    GROUP BY id
    

    【讨论】:

    • 正如我在问题中提到的我有 30 多列,我很犹豫是否在所有列上使用 GROUP BY。你给出的第二个问题对我来说似乎很合适。
    • @GopinathS - 您能否澄清一下 - 您有 30 多个列要排除(类似于电子邮件列)或包含到输出中?
    • @MikhailBerlyant - 我想包含除电子邮件列之外的 30 多个列
    • 因此,在以上两个选项中 - 您需要在 GROUP BY 中输入 30 多个列名或 30 多次 ANY_VALUE(column_name) + 30 多次各自的别名。正确的?在我看来,这并不能真正解决您的问题(当然仍然是很好的答案)
    猜你喜欢
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多