Извлечение неизвестных значений на основе последовательности значений столбца, не относящейся к схеме - PullRequest
1 голос
/ 31 мая 2019

Я хочу возвращать и работать со значениями времени на основе связанных с ними значений событий, но только если происходит определенная последовательность событий. Упрощенный пример таблицы ниже:

+--------+------------+-------+-------------+-------+-------------+-------+-------------+-------+-------------+-------+
|   id   |   event1   | time1 |   event2    | time2 |   event3    | time3 |   event4    | time4 |   event5    | time5 |
+--------+------------+-------+-------------+-------+-------------+-------+-------------+-------+-------------+-------+
| abc123 | firstevent | 10:00 | secondevent | 10:01 | thirdevent  | 10:02 | fourthevent | 10:03 | fifthevent  | 10:04 |
| abc123 | thirdevent | 10:10 | secondevent | 10:11 | thirdevent  | 10:12 | firstevent  | 10:13 | secondevent | 10:14 |
| def456 | thirdevent | 10:20 | firstevent  | 10:21 | secondevent | 10:22 | thirdevent  | 10:24 | fifthevent  | 10:25 |
+--------+------------+-------+-------------+-------+-------------+-------+-------------+-------+-------------+-------+

Для этой таблицы мы хотим получить время, когда эта конкретная последовательность событий происходит: firstevent, secondevent, thirdevent и конечное событие любого ненулевого значения. Значение соответствующих возвращенных записей будет следующим:

+--------+------------+-------+-------------+-------+-------------+-------+-------------+-------+------------+-------+
|   id   |   event1   | time1 |   event2    | time2 |   event3    | time3 |   event4    | time4 |   event5   | time5 |
+--------+------------+-------+-------------+-------+-------------+-------+-------------+-------+------------+-------+
| abc123 | firstevent | 10:00 | secondevent | 10:01 | thirdevent  | 10:02 | fourthevent | 10:03 | null       | null  |
| null   | null       | null  | null        | null  | null        | null  | null        | null  | null       | null  |
| def456 | null       | null  | firstevent  | 10:21 | secondevent | 10:22 | thirdevent  | 10:24 | fifthevent | 10:26 |
+--------+------------+-------+-------------+-------+-------------+-------+-------------+-------+------------+-------+

Как показано выше, столбцы не имеют отношения к появлению последовательности, при этом возвращаются два результата, начиная с обоих столбцов event1 и event2, поэтому решение должно быть независимым и поддерживать n столбцов. Затем эти значения можно агрегировать по последнему ненулевому событию, которое происходит в последовательности после 3 фиксированных переменных, чтобы получить что-то вроде следующего:

+-------------+-------------------------------+
| FinalEvent  | AverageTimeBetweenFinalEvents |
+-------------+-------------------------------+
| fourthevent | 1:00                          |
| fifthevent  | 2:00                          |
+-------------+-------------------------------+

1 Ответ

2 голосов
/ 31 мая 2019

Ниже для BigQuery Standard SQL

#standardSQL
WITH search_events AS (
  SELECT ['firstevent', 'secondevent', 'thirdevent'] search
), temp AS (
  SELECT *, REGEXP_EXTRACT(events, CONCAT(search, r',(\w*)')) FinalEvent
  FROM (
    SELECT id, [time1, time2, time3, time4, time5] times,
      (SELECT STRING_AGG(event) FROM UNNEST([event1, event2, event3, event4, event5]) event) events,
      (SELECT STRING_AGG(search) FROM UNNEST(search) search) search
    FROM `project.dataset.table`, search_events 
  )
)
SELECT FinalEvent, 
  times[SAFE_OFFSET(ARRAY_LENGTH(REGEXP_EXTRACT_ALL(REGEXP_EXTRACT(events, CONCAT(r'(.*?)', search, ',', FinalEvent )), ',')) + 3)] time
FROM temp
WHERE IFNULL(FinalEvent, '') != ''  

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

Row FinalEvent  time     
1   fourthevent 10:03    
2   fifthevent  10:25    

Итак, как вы можете видеть - все окончательные событияизвлечено вместе с их соответствующим временем
Теперь вы можете сделать здесь любую аналитику, которая вам нужна - я не был уверен в логике AverageTimeBetweenFinalEvents, поэтому я оставляю это вам - особенно потому, что я думаю, что основной фокус вопроса былизвлечение этих заключительных событий

Не могли бы вы предоставить логику этого утверждения, пожалуйста?
times[SAFE_OFFSET(ARRAY_LENGTH(REGEXP_EXTRACT_ALL(REGEXP_EXTRACT(events, CONCAT(r'(.*?)', search, ',', FinalEvent )), ',')) + 3)] time

Конечно, надежда ниже помогает получитьлогика этого выражения

enter image description here

  1. собрать регулярное выражение, чтобы извлечь список событий, произошедших до соответствующих событий
  2. извлечь эти события
  3. извлечь все запятые в массив
  4. вычислить позицию конечного события, взяв число запятых в указанном выше массиве + 3 (три - для отражения количества позиций в последовательности поиска)
  5. извлечь соответствующее время как элемент массива times
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...