从 JSON 列中提取数据

Extract data from JSON column

我想从 json 列中提取一个值。

架构是(- 第一级,-- 第二级):

Column Name | Type | Mode

event_params RECORD NULLABLE

-key STRING NULLABLE

-value RECORD NULLABLE

--string_value STRING NULLABLE

--int_value INTEGER NULLABLE

目前我是这样提取一个值的:

SELECT
  (
  SELECT
    event_params.value.string_value
  FROM
    UNNEST(event_params) event_params
  WHERE
    event_params.key = 'user_id') AS user_id
FROM `my_db`

有没有更好的方法来处理这个任务?

假设:

  • event_params结构 类型的数组。
  • user_id 是每个 event_params
  • 中的唯一键

以下代码风格是可能的:

-- 1. use JOIN instead of scalar subquery in SELECT list
WITH my_db AS (
  SELECT [
    STRUCT('user_id' AS key, STRUCT('111111' AS string_value, 111111 AS int_value) AS value),
    STRUCT('cust_id' AS key, STRUCT('222222' AS string_value, 222222 AS int_value) AS value)
  ] AS event_params
)
SELECT e.value.string_value AS user_id
  FROM `my_db`, UNNEST(event_params) e WHERE e.key = 'user_id';

您可以定义一个 UDF 以从具有 key-value 对的结构数组中提取值。 Google 在 public.

中提供了一些有用的 UDF
-- 2. Use a UDF to extract a value with key 'user_id'
WITH my_db AS (
  SELECT [
    STRUCT('user_id' AS key, STRUCT('111111' AS string_value, 111111 AS int_value) AS value),
    STRUCT('cust_id' AS key, STRUCT('222222' AS string_value, 222222 AS int_value) AS value)
  ] AS event_params
)
SELECT bqutil.fn.get_value('user_id', event_params).string_value AS user_id
  FROM `my_db`;

以上查询将 return 相同的输出: