СЛЕДУЕТ ПРИСОЕДИНИТЬСЯ К самой последней дате или датам в Google BigQuery - PullRequest
1 голос
/ 23 сентября 2019

Моя проблема похожа на LEFT JOIN ON на самую последнюю дату в Google BigQuery Однако я хотел бы присоединиться к возможным 1 (или более) последним дням, если существует более 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      |

Что я хочу сделать, это

  1. Длякаждая строка в Таблице A SQL LEFT JOIN самая последняя запись в Таблице B, которая предшествует ей.
  2. Когда существует более одной возможности, возьмите последнюю.
  3. Когда существует более одной изто же имя в таблице 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 Ответ

0 голосов
/ 24 сентября 2019

Ниже для BigQuery Standard 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      

Обратите внимание: в Таблице A нет способа определитькоторый является первым и вторым для обработки между a и h.То же самое для y и z в Таблице B.Чтобы сделать это различие - вам нужно иметь / добавить какое-то дополнительное правило, которое определит порядок вышеупомянутых.Для простоты (и в любом случае, это единственный доступный вариант с вашим образцом) Я использую алфавитный порядок соответствующих полей a_data и b_data

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...