【问题标题】:Parse JSON value having dynamic keys in column and convert JSON to record column structure in BigQuery解析列中具有动态键的 JSON 值并将 JSON 转换为 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

【问题讨论】:

    标签: google-bigquery


    【解决方案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(\d{4})') year, 
              REGEXP_EXTRACT(kv, r'm(\d{2})') month, 
              IFNULL(REGEXP_EXTRACT(kv, r'w\d{2}'), 'w0') week,
              REGEXP_EXTRACT(kv, r': (\d*)') value
            FROM UNNEST(REGEXP_EXTRACT_ALL(json, r'"y\d{4}m\d{2}(?:w\d{2})?": \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(\d{4})') year, 
              REGEXP_EXTRACT(kv, r'm(\d{2})') month, 
              IFNULL(REGEXP_EXTRACT(kv, r'w\d{2}'), 'w0') week,
              REGEXP_EXTRACT(kv, r': (\d*)') value
            FROM UNNEST(REGEXP_EXTRACT_ALL(json, r'"y\d{4}m\d{2}(?:w\d{2})?": \d*')) kv
          )
          GROUP BY year, month
        )
        GROUP BY year
      ) AS json
    FROM `project.dataset.table`  
    

    结果

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

    【讨论】:

    • 谢谢@Mikhail Berlyant,这正是我想要的。
    • 当然。请考虑投票 - 这在 SO 上同样重要 :o)
    • 投票是指接受答案还是别的什么?我会这样做的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多