You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BigQuery中解析JSON:提取数组首行并完全扁平化数据表

问题:BigQuery扁平化JSON数组并仅保留第一行数据

我在BigQuery中解析JSON数据,其中包含一个多列多行的数组。我需要将数组展开获取所有列,但只保留每个数组的第一行,最终得到完全扁平化的表。

我试过下面的写法,但结果会返回一个结构体。想知道把表完全扁平化的最简单方法是什么?

SELECT
  _airbyte_ab_id,
  ARRAY(
  SELECT
    AS STRUCT
    JSON_EXTRACT_SCALAR(balances, "$.total_balance.value") as value,
    JSON_EXTRACT_SCALAR(balances, "$.total_balance.currency_code") as currency
  FROM
    UNNEST(JSON_EXTRACT_ARRAY(_airbyte_data, "$.balances")) AS balances )[SAFE_OFFSET(0)] AS balances
FROM
 (select "1" as _airbyte_ab_id, JSON '{"balances":[{"total_balance":{"value":"1.68","currency_code":"EUR"},"withheld_balance":{"value":"0.00","currency_code":"EUR"},"currency":"EUR","available_balance":{"value":"1.68","currency_code":"EUR"},"primary":true},{"total_balance":{"value":"0.00","currency_code":"USD"},"withheld_balance":{"value":"0.00","currency_code":"USD"},"currency":"USD","available_balance":{"value":"0.00","currency_code":"USD"}}],"account_id":"VVULCKAL8HAHG","last_refresh_time":"2022-11-25T01:29:59Z","as_of_time":"2022-03-06T00:00:00+00:00"}' as _airbyte_data)

我尝试在JSON_EXTRACT_SCALAR中添加balances[SAFE_OFFSET(0)],但BigQuery不允许这样操作。


解决方案

方法1:先提取数组首元素再解析字段

直接通过[SAFE_OFFSET(0)]取出数组的第一个元素,再针对这个元素解析所需字段,避免生成结构体:

SELECT
  _airbyte_ab_id,
  JSON_EXTRACT_SCALAR(first_balance, "$.total_balance.value") AS value,
  JSON_EXTRACT_SCALAR(first_balance, "$.total_balance.currency_code") AS currency,
  -- 可按需添加其他字段,比如可用余额、币种等
  JSON_EXTRACT_SCALAR(first_balance, "$.available_balance.value") AS available_value,
  JSON_EXTRACT_SCALAR(first_balance, "$.currency") AS currency_code
FROM
  (SELECT 
    _airbyte_ab_id,
    -- 取出balances数组的第一个元素
    JSON_EXTRACT_ARRAY(_airbyte_data, "$.balances")[SAFE_OFFSET(0)] AS first_balance
   FROM
    (SELECT "1" AS _airbyte_ab_id, JSON '{"balances":[{"total_balance":{"value":"1.68","currency_code":"EUR"},"withheld_balance":{"value":"0.00","currency_code":"EUR"},"currency":"EUR","available_balance":{"value":"1.68","currency_code":"EUR"},"primary":true},{"total_balance":{"value":"0.00","currency_code":"USD"},"withheld_balance":{"value":"0.00","currency_code":"USD"},"currency":"USD","available_balance":{"value":"0.00","currency_code":"USD"}}],"account_id":"VVULCKAL8HAHG","last_refresh_time":"2022-11-25T01:29:59Z","as_of_time":"2022-03-06T00:00:00+00:00"}' AS _airbyte_data))

方法2:UNNEST后过滤首行

如果需要处理多组数据(每个_airbyte_ab_id对应一个数组),可以用UNNEST展开数组,再通过窗口函数筛选出每个分组的第一行:

SELECT
  _airbyte_ab_id,
  JSON_EXTRACT_SCALAR(balances, "$.total_balance.value") AS value,
  JSON_EXTRACT_SCALAR(balances, "$.total_balance.currency_code") AS currency
FROM
  (SELECT "1" AS _airbyte_ab_id, JSON '{"balances":[{"total_balance":{"value":"1.68","currency_code":"EUR"},"withheld_balance":{"value":"0.00","currency_code":"EUR"},"currency":"EUR","available_balance":{"value":"1.68","currency_code":"EUR"},"primary":true},{"total_balance":{"value":"0.00","currency_code":"USD"},"withheld_balance":{"value":"0.00","currency_code":"USD"},"currency":"USD","available_balance":{"value":"0.00","currency_code":"USD"}}],"account_id":"VVULCKAL8HAHG","last_refresh_time":"2022-11-25T01:29:59Z","as_of_time":"2022-03-06T00:00:00+00:00"}' AS _airbyte_data),
  UNNEST(JSON_EXTRACT_ARRAY(_airbyte_data, "$.balances")) AS balances WITH OFFSET AS pos
QUALIFY ROW_NUMBER() OVER(PARTITION BY _airbyte_ab_id ORDER BY pos) = 1

这两种方法都能直接生成扁平化的表结构,无需嵌套结构体。


内容的提问来源于stack exchange,提问作者volderette

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:35:23