Google BigQuery:检索每行的最后一个版本

Posted

技术标签:

【中文标题】Google BigQuery:检索每行的最后一个版本【英文标题】:Google BigQuery: retrieve last version of each row 【发布时间】:2017-07-10 14:33:32 【问题描述】:

我有一个包含所有资源版本的 Google BigQuery 表。每次创建/更新/删除资源时都会添加一个新行,并增加版本号(此数字将是添加行时的时间戳

+-------+------------+--------+-------+-------------+
|  ID   | ResourceID | Action | Count |  Timestamp  |
+-------+------------+--------+-------+-------------+
| ABC_1 | ABC        | CREATE |    10 | timestamp |
| ABC_2 | ABC        | UPDATE |     8 | timestamp |
| ABC_3 | ABC        | UPDATE |     4 | timestamp |
| ABC_4 | ABC        | DELETE |     4 | timestamp |
| -     |            |        |       |             |
| DEF_1 | DEF        | CREATE |    10 | timestamp |
| DEF_2 | DEF        | DELETE |    10 | timestamp |
| -     |            |        |       |             |
| GHJ_1 | GHJ        | CREATE |    10 | timestamp |
| -     |            |        |       |             |
| KLM_1 | KLM        | CREATE |    10 | timestamp |
| KLM_2 | KLM        | UPDATE |     5 | timestamp |
+-------+------------+--------+-------+-------------+
ID:行的唯一ID,包含ResourceID加上版本标识 ResourceID:发生操作的资源的 ID 操作:对资源执行的操作 计数:与资源关联的值 时间戳:添加行的时间戳(与唯一 ID 相同)

我需要一个查询来检索每个资源的所有最新版本

+-------+------------+--------+-------+-------------+
|  ID   | ResourceID | Action | Count |  Timestamp  |
+-------+------------+--------+-------+-------------+
| ABC_4 | ABC        | DELETE |     4 | timestamp |
| DEF_2 | DEF        | DELETE |    10 | timestamp |
| GHJ_1 | GHJ        | CREATE |    10 | timestamp |
| KLM_2 | KLM        | UPDATE |     5 | timestamp |
+-------+------------+--------+-------+-------------+

此外,所有处于DELETE 状态的资源都需要忽略。 所以这是我正在寻找的最终输出

+-------+------------+--------+-------+-------------+
|  ID   | ResourceID | Action | Count |  Timestamp  |
+-------+------------+--------+-------+-------------+
| GHJ_1 | GHJ        | CREATE |    10 | timestamp |
| KLM_2 | KLM        | UPDATE |     5 | timestamp |
+-------+------------+--------+-------+-------------+

这是我的查询

SELECT ResourceId, Count
FROM worklog_*
WHERE ID IN (
    SELECT max(ID)
    FROM worklog_*
    GROUP BY WorklogID
) AND Action != DELETE

这不是真正的 BigQuery 查询,但足以理解行为。 如果可以比较 ID 列的值,则此查询工作正常,这就是我选择加入 ResourceId 和 Timestamp 的原因,MAX() 值将始终提供最后状态

这是最好的方法吗?有没有人对进行这种提取的更好方法提出建议?

【问题讨论】:

【参考方案1】:

对于 BigQuery 标准 SQL

#standardSQL
WITH worklog AS (
  SELECT 'ABC_1' AS ID, 'ABC' AS ResourceID, 'CREATE' AS Action, 10 AS COUNT UNION ALL
  SELECT 'ABC_2', 'ABC', 'UPDATE', 8 UNION ALL
  SELECT 'ABC_3', 'ABC', 'UPDATE', 4 UNION ALL
  SELECT 'ABC_4', 'ABC', 'DELETE', 4 UNION ALL
  SELECT 'DEF_1', 'DEF', 'CREATE', 10 UNION ALL
  SELECT 'DEF_2', 'DEF', 'DELETE', 10 UNION ALL
  SELECT 'GHJ_1', 'GHJ', 'CREATE', 10 UNION ALL
  SELECT 'KLM_1', 'KLM', 'CREATE', 10 UNION ALL
  SELECT 'KLM_2', 'KLM', 'UPDATE', 5 
)
SELECT * EXCEPT(Last)
FROM (
  SELECT *,
    ROW_NUMBER() OVER(PARTITION BY ResourceID ORDER BY ID DESC) AS Last
  FROM worklog
  WHERE Action != 'DELETE'
)
WHERE Last = 1
-- ORDER BY ID

【讨论】:

在这种特定情况下,关于 EXCEPT() 子句的任何解释?我很困惑这是如何工作的 EXCEPT 允许您从最终输出中排除“Last”字段 哦,我明白了。谢谢你。我以为 EXCEPT 用于组合 2 个或多个结果集并返回结果集 1 中存在但结果集 2 中不存在的数据。我只知道 EXCEPT 可用于排除列。 @Frais Afiriansyah:一方面,有一个 EXCEPT 运算符对集合进行操作并计算它们的差异。这是由大多数数据库系统(有时也称为 MINUS)实现的。另一方面,BigQuery 还在星号后的 select 子句中提供关键字 EXCEPT 以排除列被选中:cloud.google.com/bigquery/docs/reference/standard-sql/…

以上是关于Google BigQuery:检索每行的最后一个版本的主要内容,如果未能解决你的问题,请参考以下文章

可以使用 Google Prediction API 从 bigquery 表中检索相似的行吗?

如何检索每行中的最后更新信息

获取 Google BigQuery 中值的最后一次更改时间

是否可以编写一个 BigQuery 来检索 PyPI 下载的分箱计数?

如何提高 BigQuery 读取性能

Google BigQuery 中超出的资源