假设我在BQ中有以下记录:
id name age timestamp
1 "tom" 20 2019-01-01
然后,我使用流API来“附加”附加数据-https://cloud.google.com/bigquery/streaming-data-into-bigquery,对此记录执行两次“更新”。这主要是为了避免BQ强制执行的更新配额(这是我们拥有的高性能应用程序)。
然后,我将两个编辑附加到表中,一个更新仅修改name
,然后一个更新仅修改age
。这是更新后的三个记录:
id name age timestamp
1 "tom" 20 2019-01-01
1 "Tom" null 2019-02-01
1 null 21 2019-03-03
然后,我想查询该记录以获取最新的信息。这是我的开始方式:
SELECT id, **name**, **age**,max(timestamp)
FROM table
GROUP BY id
-- 1,"Tom",21,2019-03-03
在这里如何获得正确的姓名和年龄?请注意,一条记录可能有成千上万的更新,因此,如果可能的话,我不想编写1000个case语句。
由于各种其他原因,我通常一次不会拥有所有行数据,而只会拥有RowID + FieldName + FieldValue。
我想这里的计划B是执行查询以获取当前数据,然后添加我的更改以插入新行,但是我希望有一种方法可以一次性执行此操作而不必执行两次查询。
答案 0 :(得分:4)
以下是用于BigQuery标准SQL
#standardSQL
SELECT id,
ARRAY_AGG(name IGNORE NULLS ORDER BY ts DESC LIMIT 1)[OFFSET(0)] name,
ARRAY_AGG(age IGNORE NULLS ORDER BY ts DESC LIMIT 1)[OFFSET(0)] age,
MAX(ts) ts
FROM `project.dataset.table`
GROUP BY id
您可以使用问题中的示例数据来进行测试,如上示例所示
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 id, "tom" name, 20 age, DATE '2019-01-01' ts UNION ALL
SELECT 1, "Tom", NULL, '2019-02-01' UNION ALL
SELECT 1, NULL, 21, '2019-03-03'
)
SELECT id,
ARRAY_AGG(name IGNORE NULLS ORDER BY ts DESC LIMIT 1)[OFFSET(0)] name,
ARRAY_AGG(age IGNORE NULLS ORDER BY ts DESC LIMIT 1)[OFFSET(0)] age,
MAX(ts) ts
FROM `project.dataset.table`
GROUP BY id
有结果
Row id name age ts
1 1 Tom 21 2019-03-03
答案 1 :(得分:0)
这是在标准SQL中应用解析函数的经典案例。
这是您达到目标的方法:
select id, name, age from (
select id, name, age, ts, rank() over (partition by id order by ts desc) rnk
from `yourdataset.yourtable`
)
where rnk = 1
这将基于id
将您的记录分组,并选择最近的ts
的记录(表示为给定id
添加的最近记录)。