如何在 BigQuery 中将多行聚合为一行?
How to aggregate multiple rows into one in BigQuery?
假设您有一个包含多行的非规范化架构,如下所示:
uuid | property | value
------------------------------------------
abc | first_name | John
abc | last_name | Connor
abc | age | 26
...
所有行的同一组属性,不一定排序。 如何创建 table 例如使用 BigQuery(即无客户端):
Table user_properties:
uuid | first_name | last_name | age
--------------------------------------------------------
abc | John | Connor | 26
在传统的 SQL 中有 "STUFF" 关键字用于此目的。
如果我至少可以 得到按 uuid 排序的结果会更容易,这样客户端就不需要加载整个 table (4GB) 来排序-- 可以通过顺序扫描具有相同 uuid 的行来混合每个实体。但是,这样的查询:
SELECT * FROM user_properties ORDER BY uuid;
超出了 BigQuery 中的可用资源(使用 allowLargeResults 禁止 ORDER BY)。似乎我无法在 BigQuery 中对大型 table (4GB) 进行排序,除非我订阅了高端机器。有什么想法吗?
SELECT
uuid,
MAX(IF(property = 'first_name', value, NULL)) AS first_name,
MAX(IF(property = 'last_name', value, NULL)) AS last_name,
MAX(IF(property = 'age', value, NULL)) AS age
FROM user_properties
GROUP BY uuid
Another option - no GROUP'ing involved
SELECT uuid, first_name, last_name, age
FROM (
SELECT
uuid,
LEAD(value, 1) OVER(PARTITION BY uuid ORDER BY property) AS first_name,
LEAD(value, 2) OVER(PARTITION BY uuid ORDER BY property) AS last_name,
value AS age,
property = 'age' AS anchor
FROM user_properties
)
HAVING anchor
假设您有一个包含多行的非规范化架构,如下所示:
uuid | property | value
------------------------------------------
abc | first_name | John
abc | last_name | Connor
abc | age | 26
...
所有行的同一组属性,不一定排序。 如何创建 table 例如使用 BigQuery(即无客户端):
Table user_properties:
uuid | first_name | last_name | age
--------------------------------------------------------
abc | John | Connor | 26
在传统的 SQL 中有 "STUFF" 关键字用于此目的。
如果我至少可以 得到按 uuid 排序的结果会更容易,这样客户端就不需要加载整个 table (4GB) 来排序-- 可以通过顺序扫描具有相同 uuid 的行来混合每个实体。但是,这样的查询:
SELECT * FROM user_properties ORDER BY uuid;
超出了 BigQuery 中的可用资源(使用 allowLargeResults 禁止 ORDER BY)。似乎我无法在 BigQuery 中对大型 table (4GB) 进行排序,除非我订阅了高端机器。有什么想法吗?
SELECT
uuid,
MAX(IF(property = 'first_name', value, NULL)) AS first_name,
MAX(IF(property = 'last_name', value, NULL)) AS last_name,
MAX(IF(property = 'age', value, NULL)) AS age
FROM user_properties
GROUP BY uuid
Another option - no GROUP'ing involved
SELECT uuid, first_name, last_name, age
FROM (
SELECT
uuid,
LEAD(value, 1) OVER(PARTITION BY uuid ORDER BY property) AS first_name,
LEAD(value, 2) OVER(PARTITION BY uuid ORDER BY property) AS last_name,
value AS age,
property = 'age' AS anchor
FROM user_properties
)
HAVING anchor