【发布时间】:2019-10-03 03:32:18
【问题描述】:
我正在使用 BigQuery 标准 SQL 方言。
我有一个列,我知道它是一个 JSON 字典数组。
数组长度随行变化。
我想将其展平,以便可以访问数组中每个字典的 JSON 元素。
例如,假设我有两条记录。第一个 id 为 1,在 JSON 列中,有这个
[
{"key1":"val1a", "key2": "val1b"},
{"key1":"val1c", "key2": "val1d"}
]
第二个有一个id 为2,并且在JSON 列中有
[{"key1":"val2a", "key2":"val2b"}]
我的目标是
id | key1 | key2 | offset
---------------------------
1 | val1a | val1b | 1
1 | val1c | val1d | 2
2 | val2a | val2b | 1
(虽然我可以没有偏移列)
看起来像这样的东西可以工作......
WITH table AS (
SELECT 1 as id,['{"key1":"val1a", "key2": "val1b"}','{"key1":"val1c", "key2": "val1d"}'] as array_column
UNION ALL
SELECT 2 as id,['{"key1":"val2a", "key2":"val2b"}'] as array_column)
SELECT id,
json_extract_scalar(flattened_array, '$.key1') as key1,
json_extract_scalar(flattened_array, '$.key2') as key2
FROM table t
CROSS JOIN UNNEST(t.array_column) AS flattened_array
事实上,该查询返回我期望的表(减去偏移列,添加起来很简单)
问题在于 BigQuery 不明白这个东西是一个类似 JSON 的字符串数组。它认为整个事情就是一根大绳子,我不知道如何说服它。编辑我的示例以模拟这种类型混淆说明了问题:
WITH table AS (
SELECT 1 as id,'[{"key1":"val1a", "key2": "val1b"},{"key1":"val1c", "key2": "val1d"}]' as array_column
UNION ALL
SELECT 2 as id,'[{"key1":"val2a", "key2":"val2b"}]' as array_column)
SELECT id,
json_extract_scalar(flattened_array, '$.key1') as key1,
json_extract_scalar(flattened_array, '$.key2') as key2
FROM table t
CROSS JOIN UNNEST(t.array_column) AS flattened_array
这里,验证器会抱怨,因为 UNNEST 中引用的值必须是数组。 UNNEST 在 [29:23] 包含 STRING 类型的表达式
现在我们正处于问题的核心。是否有一些明显的方法可以让 BigQuery 理解这个字符串是一个有效的 JSON 字典数组?也许我忽略了一些JSON_* 函数会使数组变平?或者以某种方式将CAST 这个东西放到一个数组中?
【问题讨论】:
-
如果数组始终具有相同的结构,您应该将 json 数据作为结构数组导入 - 将其转换为 bigquery 可以理解的格式。
标签: json google-bigquery