在 Google BigQuery 中的最近一个或多个日期上左加入

Posted

技术标签:

【中文标题】在 Google BigQuery 中的最近一个或多个日期上左加入【英文标题】:LEFT JOIN ON most recent date or dates in Google BigQuery 【发布时间】:2019-09-23 18:51:59 【问题描述】:

我的问题类似于LEFT JOIN ON most recent date in Google BigQuery 但是,如果表 A 中有超过 1 个同名,我想在最近几天(或更多)加入。

TABLE A

| name | timestamp           | a_data |
| ---- | ------------------- | ------ |
| 1    | 2018-01-01 11:10:00 | a      |
| 1    | 2018-01-01 11:10:00 | h      |
| 2    | 2018-01-01 12:20:00 | b      |
| 3    | 2018-01-01 13:30:00 | c      |

TABLE B

| name | timestamp           | b_data |
| ---- | ------------------- | ------ |
| 1    | 2018-01-01 11:00:00 | w      |
| 1    | 2018-01-01 10:30:00 | i      |
| 1    | 2018-01-01 10:00:00 | j      |
| 2    | 2018-01-01 12:00:00 | x      |
| 3    | 2018-01-01 13:00:00 | y      |
| 3    | 2018-01-01 13:10:00 | y      |
| 3    | 2018-01-01 13:10:00 | z      |

我想做的是

    对于表 A SQL LEFT JOIN 中的每一行,表 B 中的最新记录早于它。 如果有多种可能性,请选择最后一种。 当表A中有多个同名时,不要取最后一个,而是取倒数第二个。等等。

基本上,这意味着如果可能,我想将表 A 中的每一行与表 B 中的最新(如果尚未使用)行配对,否则只需删除该行。

目标结果

| name | timestamp           | a_data | b_data |
| ---- | ------------------- | ------ | ------ |
| 1    | 2018-01-01 11:10:00 | a      | w      |
| 1    | 2018-01-01 11:10:00 | h      | i      | <-- note h, i
| 2    | 2018-01-01 12:20:00 | b      | x      |
| 3    | 2018-01-01 13:30:00 | c      | z      | <-- note z, not y

另外,实际上有 3 列(包括名称)是每个表中每一行的标识符。

是否需要迭代或者我可以通过其他方式进行迭代吗?我尝试了上一个问题中的所有答案,但我没有让它工作。非常感谢任何帮助!

【问题讨论】:

【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
SELECT * FROM (
  SELECT name, 
    ARRAY_AGG(STRUCT(a_ts AS `timestamp`, a_data) ORDER BY a_ts DESC, a_data)[SAFE_OFFSET(ROW_NUMBER() OVER(PARTITION BY name ORDER BY b_ts DESC, b_data DESC) - 1)].*, 
    b_data 
  FROM (
    SELECT name, b_data, b.timestamp AS b_ts, a.timestamp AS a_ts, a_data
    FROM `project.dataset.tableB` b
    LEFT JOIN `project.dataset.tableA` a
    USING(name)
  )
  WHERE b_ts <= a_ts
  GROUP BY name, b_data, b_ts
)
WHERE NOT `timestamp` IS NULL  

如果适用于您问题的样本数据 - 结果是

Row name    timestamp           a_data  b_data   
1   1       2018-01-01 11:10:00 a       w    
2   1       2018-01-01 11:10:00 h       i    
3   2       2018-01-01 12:20:00 b       x    
4   3       2018-01-01 13:30:00 c       z      

请注意:在 TableA 中,无法确定在 ah 之间要处理的第一个和第二个。与表 B 中的 yz 相同。为了做出这种区分 - 您需要拥有/添加一些额外的规则来定义上述规则的顺序。为简单起见(无论如何,这是您的样本唯一可用的方式)我使用各个 a_datab_data 字段的字母顺序

【讨论】:

以上是关于在 Google BigQuery 中的最近一个或多个日期上左加入的主要内容,如果未能解决你的问题,请参考以下文章

我们可以将 BigQuery 中的数据导入 Google 表格吗?

从 Google BigQuery 中过滤或替换非英文字符

如何在 Google BigQuery 中执行三元运算?

按日期时间 Google BigQuery 分区

在 BigQuery 或 Google Data Studio 中获取上个月的数据

将数据从 Google 永久磁盘加载到 BigQuery?