【问题标题】:BigQuery ARRAY_AGG with batches带有批次的 BigQuery ARRAY_AGG
【发布时间】:2020-10-01 21:40:00
【问题描述】:

是否有一些简单的方法可以将值聚合成批次(带保存顺序)

从这里

key | value
----+------
a   |  1
a   |  2
a   |  3
a   |  4
a   |  5
a   |  6

b   |  9
b   |  8
b   |  7
b   |  6
b   |  5
b   |  4

到这里

key | batches
----+-------------------------------------------------------------
a   | [{'values': [1, 2]}, {'values': [3, 4]}, {'values': [5, 6]}]
b   | [{'values': [9, 8]}, {'values': [7, 6]}, {'values': [5, 4]}]

{'values': [1, 2]} - 结构
[{'values': [1, 2]}, {'values': [3, 4]}, {'values': [5, 6]}] - 重复结构

【问题讨论】:

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


    【解决方案1】:

    对于 BigQuery 标准 SQL

    是否有一些简单的方法可以将值聚合成批次(带有保存顺序

    注意;为了“保存订单”-您需要在数据中显示此订单-我假设您有一些定义该订单的东西(我为此使用ts字段)-通常是时间戳或订单/位置数据类型等。

    所以,下面是实现上述目标的起点

    #standardSQL
    SELECT key, 
      ARRAY_AGG(value ORDER BY pos) AS batch,
      DIV(pos - 1, 2) batch_num
    FROM (
      SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) pos,
        DIV(ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) - 1, 2) batch
      FROM `project.dataset.table`
    )
    GROUP BY key, batch_num
       
    

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

    从这里,您可以将上述结果打包成您需要的任何最终格式 - 例如

    #standardSQL
    SELECT key, ARRAY_AGG(batch ORDER BY batch_num) batches
    FROM (
      SELECT key, 
        STRUCT(ARRAY_AGG(value ORDER BY pos) AS values) batch,
        DIV(pos - 1, 2) batch_num
      FROM (
        SELECT *, 
          ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) pos,
          DIV(ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) - 1, 2) batch
        FROM `project.dataset.table`
      )
      GROUP BY key, batch_num
    )
    GROUP BY key
    

    给出以下输出(非常接近您问题中的预期示例)

    [
      {
        "key": "a",
        "batches": [
          {
            "values": [
              "1",
              "2"
            ]
          },
          {
            "values": [
              "3",
              "4"
            ]
          },
          {
            "values": [
              "5",
              "6"
            ]
          }
        ]
      },
      {
        "key": "b",
        "batches": [
          {
            "values": [
              "9",
              "8"
            ]
          },
          {
            "values": [
              "7",
              "6"
            ]
          },
          {
            "values": [
              "5",
              "4"
            ]
          }
        ]
      }
    ]
    

    【讨论】:

    • 但是OVER(PARTITION BY key ORDER BY True)不保证订单?
    • 我的答案中没有看到ORDER BY True!请澄清您的评论-并在我的回答之上再次阅读注释:o)
    • 对不起。我的意思是如果源表中没有类似时间戳的东西,我想用OVER(PARTITION BY key ORDER BY True) 替换OVER(PARTITION BY key ORDER BY ts)
    • 如果您没有任何可以用作订单指示的字段 - 这意味着您的数据中没有任何订单,因此很遗憾没有什么可以保留 - 所以您可以删除订单到部分 - 所以你仍然会得到批次,但不能保证订单
    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多