如何在 BigQuery 中取消嵌套重复记录,一个数组给出列名,另一个给出列值?

问题描述

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

globalId Meta.name Meta.value
9200000104 ViewsL7D 2877
旧价格 33.47
NewPrice 33.21
9200000783 ViewsL7D 19231
旧价格 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)

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

解决方法

你可以简单地旋转表格

如果超过这三个肉名就得用动态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'),'NewPrice','3321'),('9200000783','19231'),'14.27'),'12.11');
SELECT 
`globalId`,MAX(IF (`Meta.name` = 'ViewsL7D',`Meta.value`,NULL  )) AS ViewsL7D,MAX(IF (`Meta.name` = 'OldPrice',NULL  )) AS OldPrice,MAX(IF (`Meta.name` = 'NewPrice',NULL  )) AS NewPrice
FROM table1

GROUP BY `globalId`
globalId   | ViewsL7D | OldPrice | NewPrice
:--------- | -------: | -------: | -------:
9200000104 |  2877.00 |    33.47 |  3321.00
9200000783 | 19231.00 |    14.27 |    12.11

dbfiddle here

,

考虑以下方法

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

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

enter image description here

输出是

enter image description here

,

鉴于您的表的形状,我想您有两个数组 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,[19231,14.27,12.11] AS value) AS Meta )

enter image description here

从那里你想取消你的数组并旋转它:

SELECT
  globalid,MAX(IF(name="ViewsL7D",NULL)) AS ViewsL7D,MAX(IF(name="OldPrice",NULL)) AS OldPrice,MAX(IF(name="NewPrice",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

它给出了这个 enter image description here