Нужна помощь в объединении двух таблиц и их уникальном объединении с помощью BigQuery SQL - PullRequest
0 голосов
/ 30 мая 2019

У меня есть две таблицы с разной гранулярностью в наборе данных BigQuery. Мне нужно объединить эти два и свернуть их с помощью BigQuery SQL таким образом, чтобы значение в одном из столбцов 2-й таблицы стало столбцами в итоговой таблице

Таблица 1 - tb1 выглядит так

user_id     event_date
A          2019-02-01
B          2019-02-10
C          2019-01-15

Таблица 2 - tb2 выглядит так

user_id    activity_id   activity_date
A          1             2019-01-01
A          1             2019-02-05
A          2             2019-01-15
B          2             2019-02-02
B          3             2019-02-01
C          1             2019-01-02

Я пытаюсь написать SQL-запрос для создания финальной таблицы, которая сообщает нам количество записей для каждого действия для user_id, где action_date находится в пределах (event_date - 90 дней) для этого user_id, т.е. action_date находится в 90 дни, предшествующие дате события. Таким образом, в этом случае вывод будет выглядеть следующим образом

user_id   event_date  act_1   act_2    act_3 
A         2019-02-01   1        1        0
B         2019-02-10   0        2        1
C         2019-01-15   1        0        0

столбец act_1 соответствует Activity_id = 1 и т. Д.

Есть несколько дополнительных осложнений, таких как: -

    1. Количество различных активность_ид в таблице 2 может меняться со временем. Итак, я не знаю заранее, сколько столбцов будет создано в выходной таблице.
    1. Я не могу сделать это в Python, но это должно быть сделано в BQ. Это связано с тем, что фактическая таблица 2 очень велика (42 ТБ с 31 млрд строк), и извлечение ее из BQ в другой продукт GCS для запуска python может быть громоздким.

Любая помощь приветствуется.

1 Ответ

4 голосов
/ 30 мая 2019

Ниже приведено описание BigQuery Standard SQL и просто для демонстрации подхода к повороту данных.

Если вы заранее знаете, сколько у вас различных активных_идентификаторов и их число небольшое, например три, какв вашем примере - вы сделали бы так просто, как показано ниже

#standardSQL
SELECT 
  user_id,
  event_date,
  COUNTIF(activity_id = 1) act_1,
  COUNTIF(activity_id = 2) act_2,
  COUNTIF(activity_id = 3) act_3
FROM `project.dataset.table1` t1
JOIN `project.dataset.table2` t2
USING(user_id)
GROUP BY user_id, event_date
ORDER BY user_id, event_date   

, если применить к образцу данных, как в вашем вопросе - результат будет

Row user_id event_date  act_1   act_2   act_3    
1   A       2019-02-01  2       1       0    
2   B       2019-02-10  0       1       1    
3   C       2019-01-15  1       0       0      

Но, как вы упомянули

Количество различных активность_ид в таблице 2 может меняться со временем.Итак, я не знаю заранее, сколько столбцов будет создано в выходной таблице

Итак, вам нужно сгенерировать запрос выше динамически - ниже приведен пример такого

#standardSQL
WITH activities AS (
  SELECT DISTINCT activity_id 
  FROM `project.dataset.table2`
), generate_query AS (
  SELECT CONCAT(
    'SELECT user_id, event_date',
    STRING_AGG(CONCAT(',COUNTIF(activity_id = ', CAST(activity_id AS STRING), ') act_', CAST(activity_id AS STRING)), ''),
    ' FROM `project.dataset.table1` t1 JOIN `project.dataset.table2` t2 USING(user_id) GROUP BY user_id, event_date ORDER BY user_id, event_date'
  ) AS query
  FROM activities
)
SELECT query FROM generate_query 

Опять же, если применить к вашим образцам данных - результат будет

SELECT user_id, event_date,COUNTIF(activity_id = 1) act_1,COUNTIF(activity_id = 2) act_2,COUNTIF(activity_id = 3) act_3 FROM `project.dataset.table1` t1 JOIN `project.dataset.table2` t2 USING(user_id) GROUP BY user_id, event_date ORDER BY user_id, event_date   

, если посмотреть ближе к приведенному выше результату - вы можете видеть - это именно тот запрос, который мы изначально написали вручную - но сейчасон был сгенерирован для нас - и независимо от того, сколько у вас есть отдельных activity_id (очевидно, ограничения по количеству столбцов все еще применяются) - он будет запрашивать необходимый продукт

Итак, теперь вам просто нужно скопировать текст запроса изприведенный выше результат и просто запустите его - что даст желаемый результат

Row user_id event_date  act_1   act_2   act_3    
1   A       2019-02-01  2       1       0    
2   B       2019-02-10  0       1       1    
3   C       2019-01-15  1       0       0      

Как вы можете видеть, это двухэтапный процесс - но вы можете написать его, используя клиент по вашему выбору

Примечание: я сфокусировался на сути вопроса и вообще не обращался к теме, связанной с 90 днями, - мне кажется, это была второстепенная деталь в вашем вопросе

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