解析列中具有动态键的 JSON 值并将 JSON 转换为 BigQuery 中的记录列结构

Posted

技术标签:

【中文标题】解析列中具有动态键的 JSON 值并将 JSON 转换为 BigQuery 中的记录列结构【英文标题】:Parse JSON value having dynamic keys in column and convert JSON to record column structure in BigQuery 【发布时间】:2019-08-29 03:52:55 【问题描述】:

我有一个问题,表中的一列包含 JSON 字符串。 JSON 有一些列是固定的,一些列是动态添加的,它们的计数也不是固定的。我需要帮助解决这两个问题:- - 解析此 JSON 并提取可用且动态的键的值。 - 使用键的模式和值将 JSON 列转换为记录结构。

例如。如果列中存在以下 JSON

“y2019m08w35”:0,“总计”:0,“y2019m08w33”:0,“y2019m08”:0,“y2019m08w34”:0

那么关键是y2019m08w35、y2019m08w33等,它可以是任何东西,因为它由年月和周组合而成。 现在假设我得到了 y2019m08w33 的值,那么它应该进入记录列。应该像下面这样创建

年度记录栏(2019 年)

月份 - 一年内的记录列(m08)

Week - 月(w33)内的记录列,该列将保存 y2019m08w33 的值为 0。

详情见附件截图。

Initial Value in Table

Expected Output

【问题讨论】:

【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
SELECT id, name, product_id,
  ARRAY(
    SELECT AS STRUCT year, ARRAY_AGG(STRUCT(month, weeks)) months
    FROM (
      SELECT year, month, ARRAY_AGG(STRUCT(week, value)) weeks 
      FROM (
        SELECT
          REGEXP_EXTRACT(kv, r'y(\d4)') year, 
          REGEXP_EXTRACT(kv, r'm(\d2)') month, 
          IFNULL(REGEXP_EXTRACT(kv, r'w\d2'), 'w0') week,
          REGEXP_EXTRACT(kv, r': (\d*)') value
        FROM UNNEST(REGEXP_EXTRACT_ALL(json, r'"y\d4m\d2(?:w\d2)?": \d*')) kv
      )
      GROUP BY year, month
    )
    GROUP BY year
  ) AS json
FROM `project.dataset.table`  

您可以使用您问题中的示例数据进行测试,如以下示例所示

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 2 id, 'Test2' name, 1234 product_id, '"y2019m08w35": 0, "total": 0, "y2019m08w33": 0, "y2019m08": 0, "y2019m08w34": 0' json UNION ALL
  SELECT 1 id, 'Test' name, 8338 product_id, '"y2018m08w35": 10,"y2019m08w35": 10, "y2019m08w33": 20, "y2019m08": 0, "y2019m09w34": 30, "y2019m10w34": 30, "y2019m10w35": 40' json
)
SELECT id, name, product_id,
  ARRAY(
    SELECT AS STRUCT year, ARRAY_AGG(STRUCT(month, weeks)) months
    FROM (
      SELECT year, month, ARRAY_AGG(STRUCT(week, value)) weeks 
      FROM (
        SELECT
          REGEXP_EXTRACT(kv, r'y(\d4)') year, 
          REGEXP_EXTRACT(kv, r'm(\d2)') month, 
          IFNULL(REGEXP_EXTRACT(kv, r'w\d2'), 'w0') week,
          REGEXP_EXTRACT(kv, r': (\d*)') value
        FROM UNNEST(REGEXP_EXTRACT_ALL(json, r'"y\d4m\d2(?:w\d2)?": \d*')) kv
      )
      GROUP BY year, month
    )
    GROUP BY year
  ) AS json
FROM `project.dataset.table`  

结果

希望您可以在上面调整为您真正需要的任何命名 - 注意:除非您在 Excel 或表格中进行了模型,否则您的示例中的输出列的命名是不可行的,您显然可以随意命名内容:o)

【讨论】:

谢谢@Mikhail Berlyant,这正是我想要的。 当然。请考虑投票 - 这在 SO 上同样重要 :o) 投票是指接受答案还是别的什么?我会这样做的。

以上是关于解析列中具有动态键的 JSON 值并将 JSON 转换为 BigQuery 中的记录列结构的主要内容,如果未能解决你的问题,请参考以下文章

快速解析动态键的json响应问题

swift 4 使用 Alamofire 解析没有键的 JSON

从 BigQuery 中具有无效令牌的列中解析 JSON 文件

如何解析具有相同键的不同数据类型的改造对象的json数组

MySQL数据类型 - JSON数据类型

解析文件并将其存储到具有Node js中多个值的Map函数中