带有批次的 BigQuery ARRAY_AGG

Posted

技术标签:

【中文标题】带有批次的 BigQuery ARRAY_AGG【英文标题】:BigQuery ARRAY_AGG with batches 【发布时间】: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]] - 重复结构

【问题讨论】:

【参考方案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) 如果您没有任何可以用作订单指示的字段 - 这意味着您的数据中没有任何订单,因此很遗憾没有什么可以保留 - 所以您可以删除订单到部分 - 所以你仍然会得到批次,但不能保证订单

以上是关于带有批次的 BigQuery ARRAY_AGG的主要内容,如果未能解决你的问题,请参考以下文章

带有广播连接的 Spark 流式传输

带有 STRUCTS 数组的 Bigquery python SchemaField()

如何将带有 POLYGON 的字符串类型转换为地理类型 - BigQuery

BigQuery - 通过应用脚本上传带有模式自动检测的 csv

使用 EXECUTE IMMEDIATE 保存带有动态 SQL 的 BigQuery 视图

如何为每一行使用带有 bigquery 流插入的插入 ID?