我在BigQuery中有一个表,其中包含ID字段和重复记录字段以及其他一些字段,如数据收集时间。
此表中有多个行用于每个ID,我想以某种方式为每个ID选择/合并一行。几乎每个解决方案,如选择最后一个,首先选择并在一行中聚合具有重复ID的行,在我的用例中是可以接受的,但到目前为止我无法使它们中的任何一个工作。
更确切地说,我的表有一个ID字段,在BigQuery术语中是:
{name: ID, type: STRING, mode: NULLABLE}
和重复的字段:{name: data, type: RECORD, mode: REPEATED}
以及其他一些(普通)字段。
在我的表中,每个ID都有多行,每个ID都有一个重复的字段data
。在我的查询结果中,我想要一个具有完全相同模式的表,其中每个ID只出现一次,并且其对应的data
字段是data
字段,来自原始表中出现的ID之一。 (或理想地从其所有出现中结合起来)
以下是无法解决的解决方案列表:
首先:使用
row_number() OVER (PARTITION BY ID ORDER BY collection_time) as rn ... where rn=1
原因:即使使用了“Unflatten Results”选项,BigQuery也会在使用partition by
时展平结果。
第二:选择具有最大/最小收集时间值的行:
因为:由于系统的其他部分存在一些重复,列的值对于我的表中的每个id都不是唯一的。
第三次:在其他字段中使用group by
ID与nest
/ first
。
原因:在重复记录上使用nest
会破坏记录字段中的关系。例如:SELECT ID, nest(data.a), nest(data.b)
来自:
ID data.a data.b
--------------------------
1 1a1 null
1a2 1b2
--------------------------
1 2a1 2b1
null 2b2
结果
ID data.a data.b
----------------------------
1 1a1 1b2
1a2 2b1
2a1 2b2
答案 0 :(得分:1)
您可以更轻松地使用standard SQL解决此问题(取消选中"使用旧版SQL"在"显示选项"下)。您可以将GROUP BY
与ARRAY_CONCAT_AGG
一起使用,例如:
SELECT id, ARRAY_CONCAT_AGG(data) AS data
FROM MyTable
GROUP BY id;
答案 1 :(得分:1)
在标准SQL模式下尝试以下
SELECT id, ARRAY_AGG(STRUCT(a, b)) AS data
FROM (
SELECT id, a, ROW_NUMBER() OVER() AS num
FROM YourTable, UNNEST(data) WHERE NOT a IS NULL
) FULL OUTER JOIN (
SELECT id, b, ROW_NUMBER() OVER() AS num
FROM YourTable, UNNEST(data) WHERE NOT b IS NULL
)
USING(id, num)
GROUP BY id
它会在您的问题中提供您期望的exactly
结果(消除NULL):
ID data.a data.b
----------------------------
1 1a1 1b2
1a2 2b1
2a1 2b2
如果(另一方面)你想保留原始的a / b对 - 你应该在下面使用(仍然在标准SQL模式下)
SELECT id, ARRAY_CONCAT_AGG(data) AS data
FROM YourTable
GROUP BY id
这为您提供了以下结果
ID data.a data.b
----------------------------
1 1a1 null
1a2 1b2
2a1 2b1
null 2b2
您可以针对实际表格运行查询(将YourTable
更改为实际表格 - >`project.dataset.table`),或者通过在代码前面添加相应查询并按原样运行来测试这两个查询
WITH YourTable AS (
SELECT 1 AS id, ARRAY<STRUCT<a STRING, b STRING>>[('1a1', NULL),('1a2','1b2')] AS data UNION ALL
SELECT 1 AS id, ARRAY<STRUCT<a STRING, b STRING>>[('2a1', '2b1'),(NULL,'2b2')] AS data
)