【问题标题】:Flatten an array on bigquery在 bigquery 上展平数组
【发布时间】:2020-09-02 04:54:39
【问题描述】:

我正在使用 BigQuery,并且我有一个包含嵌套字段的表,我需要将其展平才能下载该表。 我找到了解释页面(https://cloud.google.com/life-sciences/docs/how-tos/flatten-bigquery-table),但我不完全理解。

代码如下:

标准SQL

SELECT
      reference_name, start_position, end_position, reference_bases,
      call.name AS call_name
FROM
      `PROJECT_ID.BIGQUERY_DATASET.BIGQUERY_TABLE` AS t,
      t.call AS call

我明白我们为什么要写“call.name AS call_name”。但是我不明白为什么我们写“t.call AS call”?字母“t”在这里代表什么?我们为什么要写 t.call?为什么我们需要创建一个带有“AS call”的别名?

感谢您的帮助!

【问题讨论】:

  • 样本数据和期望的结果会有所帮助。

标签: sql arrays google-bigquery


【解决方案1】:

我很困惑。 “扁平化”是指重复的字段——数组。您使用unnest 将它们展平。那将是:

SELECT reference_name, start_position, end_position, reference_bases,
       call.name AS call_name
FROM `PROJECT_ID.BIGQUERY_DATASET.BIGQUERY_TABLE` t CROSS JOIN
      UNNEST(t.calls) AS call

这说明:

  • calls 是表中的重复字段。
  • calls 是一个结构体。
  • calls 有一个名为 name 的列。

我将call 列重命名为calls,因为它包含多个值——并将其与FROM 子句中的call 区分开来。

名称列正在外部查询中返回。

这是您可以运行的示例:

with `PROJECT_ID.BIGQUERY_DATASET.BIGQUERY_TABLE` as (
       select 'a' as reference_name, 1 as start_position, 5 as end_position, 'b' as reference_bases,
              array[struct('name1' as name),
                    struct('name2' as name),
                    struct('name3' as name)
                   ] calls                   
      )
SELECT reference_name, start_position, end_position, reference_bases,
       call.name AS call_name
FROM `PROJECT_ID.BIGQUERY_DATASET.BIGQUERY_TABLE` t CROSS JOIN
      UNNEST(t.calls) AS call;

【讨论】:

  • 嗨,Gordon,我的 SQL 技能还很基础,有时我遇到的任务需要超出它们的知识。我可以想象我的问题对于高级 SQL 用户来说可能是莫名其妙的,但你不知道这有多大帮助。非常感谢您抽出宝贵时间!!我真的很感激。
  • @AndyRojas 。 . .如果它对你有帮助,我很惊讶你没有接受这个答案。
  • 嗨,戈登,这两个答案都阐明了我的问题并相互补充。我试图选择两者,但它没有工作。
【解决方案2】:

但是我不明白为什么要写“t.call AS call”?字母“t”在这里代表什么?为什么要写 t.call?

字母t 是上一行表格的别名。在t.call 中,它完全限定了call 内部表的路径 - 调用是重复字段,因此它与t 一起被视为可以在连接中使用的“虚拟”表 - 在这种情况下,它是交叉连接(如逗号是 CROSS JOIN 的快捷方式)

为什么我们需要创建一个带有“AS call”的别名?

在 SELECT 语句中有对 call.name 的引用,这意味着您从该调用“虚拟表”输出名称字段。这在主表中有另一个名称列的情况下很重要,这样可以避免歧义错误
注意:如果没有任何其他名为 name 的列 - 您可以跳过调用,如下例所示

SELECT
      reference_name, start_position, end_position, reference_bases,
      name AS call_name
FROM
      `PROJECT_ID.BIGQUERY_DATASET.BIGQUERY_TABLE` AS t,
      t.call  

【讨论】:

  • 嗨,米哈伊尔,现在这更有意义了。非常感谢!!!!! :)
【解决方案3】:

试试这个link

您可以使用 unnest 实现此目的:

SELECT
  reference_name, start_position, end_position, reference_bases,
  call.name AS call_name
FROM
  `PROJECT_ID.BIGQUERY_DATASET.BIGQUERY_TABLE`,
  UNNEST(call) AS call

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    • 2020-10-18
    • 2020-03-01
    • 2020-04-10
    • 2022-10-23
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多