【问题标题】:How can I unnest a repeated record in BigQuery, with one array giving the column names and another giving column values?如何在 BigQuery 中取消嵌套重复记录,一个数组给出列名,另一个给出列值?
【发布时间】:2021-04-30 12:44:21
【问题描述】:

我在 Google BigQuery 中工作,并且有一个包含两条重复记录的数据集:一条是元素名称,另一条是元素值。我的数据集的简化版本(只有 2 个条目)如下所示:

globalId Meta.name Meta.value
9200000104 ViewsL7D 2877
OldPrice 33.47
NewPrice 33.21
9200000783 ViewsL7D 19231
OldPrice 14.27
NewPrice 12.11

我想要的是这样的表格:

globalId ViewsL7D OldPrice NewPrice
9200000104 2877 33.47 33.21
9200000783 19231 14.27 12.11

我之前没有处理过重复记录,所以我真的不知道如何解决这个问题,但到目前为止我已经尝试使用以下代码: SELECT * FROM table LEFT JOIN UNNEST(cloudmetadata)

但是当我这样做时,我保留了重复的记录,只添加了六个额外的列,在名称和值之间交替。有人可以帮忙吗?

【问题讨论】:

    标签: google-bigquery unnest


    【解决方案1】:

    您可以简单地旋转表格

    如果你有超过这三个肉名你必须使用动态sql

    CREATE TABLE table1 (
      `globalId` varchar(10),
      `Meta.name` VARCHAR(8),
      `Meta.value` DECIMAL(10,2)
    );
    
    INSERT INTO table1
      (`globalId`, `Meta.name`, `Meta.value`)
    VALUES
      ('9200000104', 'ViewsL7D', '2877'),
      ('9200000104', 'OldPrice', '33.47'),
      ('9200000104', 'NewPrice', '3321'),
      ('9200000783', 'ViewsL7D', '19231'),
      ('9200000783', 'OldPrice', '14.27'),
      ('9200000783', 'NewPrice', '12.11');
    
    SELECT 
    `globalId`,
    MAX(IF (`Meta.name` = 'ViewsL7D',`Meta.value`, NULL  )) AS ViewsL7D,
    MAX(IF (`Meta.name` = 'OldPrice',`Meta.value`, NULL  )) AS OldPrice,
    MAX(IF (`Meta.name` = 'NewPrice',`Meta.value`, NULL  )) AS NewPrice
    FROM table1
    
    GROUP BY `globalId`
    
    全球标识 |视图L7D |旧价格 |新价格 :--------- | --------: | --------: | --------: 9200000104 | 2877.00 | 33.47 | 3321.00 9200000783 | 19231.00 | 14.27 | 12.11

    db小提琴here

    【讨论】:

      【解决方案2】:

      考虑以下方法

      select globalId, 
        max(if(name = 'ViewsL7D', value, null)) as ViewsL7D,
        max(if(name = 'OldPrice', value, null)) as OldPrice,
        max(if(name = 'NewPrice', value, null)) as NewPrice
      from your_table t, t.Meta
      group by globalId    
      

      如果应用于您问题中的样本数据

      输出是

      【讨论】:

      • 你有机会尝试吗?
      【解决方案3】:

      鉴于您的桌子的形状,我想您有两个数组 namevalue 保存在 Meta 结构中。我使用以下内容重新创建了表:

      WITH
        mydata AS (
        SELECT
          9200000104 AS globalid,
          STRUCT(["ViewsL7D",
            "OldPrice",
            "NewPrice"] AS name,
            [2877,
            33.47,
            33.21] AS value) AS Meta
        UNION ALL
        SELECT
          9200000783 AS globalid,
          STRUCT(["ViewsL7D",
            "OldPrice",
            "NewPrice"] AS name,
            [19231,
            14.27,
            12.11] AS value) AS Meta )
      

      您想从那里取消嵌套数组并对其进行旋转:

      SELECT
        globalid,
        MAX(IF(name="ViewsL7D",value, NULL)) AS ViewsL7D,
        MAX(IF(name="OldPrice",value, NULL)) AS OldPrice,
        MAX(IF(name="NewPrice",value, NULL)) AS NewPrice
      FROM
        (SELECT
          globalid,
          Meta.name[OFFSET(offset_value)] name,
          Meta.value[OFFSET(offset_value)] value
        FROM mydata,
        UNNEST(Meta.value) value WITH OFFSET offset_value ORDER BY offset_value)
      GROUP BY globalid 
      ORDER BY
        globalid
      

      它给出了这个

      【讨论】:

        猜你喜欢
        • 2021-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 2018-01-26
        相关资源
        最近更新 更多