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

BigQuery中如何按JSON列键值对聚合求和?

在BigQuery中按JSON键值对分组求和的实现

需求说明

我们有一张BigQuery表,包含cost(浮点型)和labels(JSON型)两列,数据示例如下:

| cost Float | labels JSON | 
| 10         | {"key1":"value1", "key2":"vaue2"} |
| 20         | {"key1":"value3", "key2":"vaue2", "key3":"vaue4"} |
....

需要对全表中所有唯一的键值对组合,计算对应的cost总和,期望输出示例:

total_cost  key_value_pair
10          "key1:value1"
20          "key1:value3"
30          "key2:vaue2"
20          "key3:vaue4"

问题重现

尝试了以下SQL语句:

SELECT
    t.key,
    t.value,
    SUM(t.cost) AS total_cost
  FROM
    (
      SELECT
          CAST(key AS STRING) AS key,
          JSON_EXTRACT_SCALAR(label, CONCAT('$[', key, ']')) AS value,
          cost
        FROM
          `PlayGround.table1`,
          UNNEST(GENERATE_ARRAY(1, CAST(JSON_EXTRACT_SCALAR(label, '$[0]') AS BIGNUMERIC))) AS key
    ) AS t
  GROUP BY 1, 2

执行时触发报错:JSON_EXTRACT_SCALAR的第二个参数必须是常量表达式

解决方案

该需求完全可以在BigQuery中实现。报错原因是JSON_EXTRACT_SCALAR的路径参数要求是常量,不能用动态生成的变量。正确的做法是借助JSON_QUERY_ARRAY将JSON对象转换为键值对数组,再展开处理:

方案一:直接生成键值对字符串并求和

SELECT
  CONCAT(kv.key, ':', kv.value) AS key_value_pair,
  SUM(cost) AS total_cost
FROM
  `PlayGround.table1`,
  UNNEST(JSON_QUERY_ARRAY(labels, '$')) AS kv
GROUP BY
  key_value_pair
ORDER BY
  total_cost;

方案二:保留key和value字段再组合

如果需要单独保留key和value字段,可使用以下SQL:

SELECT
  kv.key,
  kv.value,
  SUM(cost) AS total_cost,
  CONCAT(kv.key, ':', kv.value) AS key_value_pair
FROM
  `PlayGround.table1`,
  UNNEST(JSON_QUERY_ARRAY(labels, '$')) AS kv
GROUP BY
  kv.key, kv.value
ORDER BY
  total_cost;

原理说明

  • JSON_QUERY_ARRAY(labels, '$')会把JSON对象转换为包含多个{"key": "xxx", "value": "xxx"}结构的数组
  • 通过UNNEST展开数组,即可获取每条数据对应的所有键值对
  • 最后按键值对分组,用SUM(cost)计算总和即可得到目标结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:13:12