Google bigquery 在Google BigQuery中的最近日期左键连接

Google bigquery 在Google BigQuery中的最近日期左键连接,google-bigquery,Google Bigquery,我的问题类似于 但是,如果表A中有多个同名的,我可能会在最近几天加入1个(或更多) 表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

我的问题类似于 但是,如果表A中有多个同名的,我可能会在最近几天加入1个(或更多)

表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      |
表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
    
    |名称|时间戳| a|U数据| b|U数据|
    | ---- | ------------------- | ------ | ------ |
    |1 | 2018-01-01 11:10:00 | a | w|
    
    |下面的1 | 2018-01-01 11:10:00 | h | i |用于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  
    

    请注意:在表a中,无法确定在
    a
    h
    之间处理的第一个和第二个。表B中的
    y
    z
    相同。要进行区分,您需要有/添加一些额外的规则来定义上述规则的顺序。为了简单起见(不管怎样,这是唯一可以使用您的示例的方法),我使用了相应的
    a_数据
    b_数据
    字段的字母顺序

    下面是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  
    
    请注意:在表a中,无法确定在
    a
    h
    之间处理的第一个和第二个。表B中的
    y
    z
    相同。要进行区分,您需要有/添加一些额外的规则来定义上述规则的顺序。为了简单起见(不管怎样,这是唯一可以使用您的示例的方法),我使用了各自
    a_数据
    b_数据
    字段的字母顺序