Подсчет вхождений последовательности событий, распределенных по нескольким строкам - PullRequest
2 голосов
/ 17 мая 2019

Таким образом, таблица содержит запись событий, последовательных по времени, например:

+-------------------------+--------+--------+------------+------------+
|        Timestamp        |   id   | event  | variable 1 | variable 2 |
+-------------------------+--------+--------+------------+------------+
| 2019-05-17 00:00:00.000 | abc123 | event1 | variable1  | null       |
| 2019-05-17 00:00:10.000 | abc123 | event2 | null       | variable2  |
| 2019-05-17 00:00:15.000 | abc123 | event3 | null       | null       |
| 2019-05-17 00:05:00.000 | abc123 | event1 | variable1  | null       |
| 2019-05-17 00:05:10.000 | abc123 | event4 | null       | null       |
| 2019-05-17 00:05:15.000 | abc123 | event3 | null       | null       |
+-------------------------+--------+--------+------------+------------+

Требуется подсчитать, сколько раз происходит определенная последовательность событий, например, event1 следует event2, чтоследует до event3.Таким образом, в приведенном выше примере код будет возвращать:

+--------+----------------+
|   id   | sequence_count |
+--------+----------------+
| abc123 |              1 |
+--------+----------------+

Последовательность event1 -> event2 -> event3 произошла один раз в наборе данных для пользователя abc123, event1 -> event4 -> event3 последовательность не учитывается.Переменная, используемая для сокращения счетчика, также может быть переключена для получения результата:

+------------+----------------+
| variable 1 | sequence_count |
+------------+----------------+
| variable1  |              1 |
+------------+----------------+

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

Ответы [ 3 ]

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

Вы можете использовать аналитическую функцию LEAD(), например:

with
x as (
  select
    event,
    lead(event) over(order by timestamp) as next_event,
    lead(event, 2) over(order by timestamp) as next_next_event
  from t
)
select count(*)
from x
where event = 'event1'
  and next_event = 'event2'
  and next_next_event = 'event3'

Добавлено :

Я не совсем уверен насчет дополнительного вопроса, который выспросил в комментариях, но мне кажется, вы хотите сгруппировать по исходной переменной .Если это так, вы можете сделать:

with
x as (
  select
    event,
    variable_1,
    lead(event) over(order by timestamp) as next_event,
    lead(event, 2) over(order by timestamp) as next_next_event
  from t
)
select variable_1, count(*)
from x
where event = 'event1'
  and next_event = 'event2'
  and next_next_event = 'event3'
group by variable_1
0 голосов
/ 17 мая 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT id, 
  ARRAY_LENGTH(
    REGEXP_EXTRACT_ALL(
      CONCAT(',', STRING_AGG(event ORDER BY Timestamp)), 
      ',event1,event2,event3')
  ) AS sequence_count
FROM `project.dataset.table`
GROUP BY id
0 голосов
/ 17 мая 2019

Я не знаю, BigQuery, но следующие только некоторые идеи.Вы должны знать стартовое событие, например, 'event1'.

WITH cteSt (rid,id,timestamp)
AS
(
  -- Get all the timestamp for the start event
  SELECT ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp), id, timestamp 
  FROM dataset 
  WHERE event='event1' -- start event
),
cteRange(id,start_ts,end_ts)
AS
(
  -- get previous time stamp as end ts for comparing
  SELECT s.id,s.timestamp,COALESCE(e.timestamp,current_ts)
  FROM cteSt s
  LEFT JOIN cteSt e
  ON s.id=e.id
  AND s.rid+1=e.rid
),
cte_Events(id, start_ts, event_sequence)
AS
(
  -- event sequence order by ts
  SELECT r.id,r.start_ts, GROUP_CONCAT(d.event ORDER BY d.timestamp SEPARATOR ',')
  FROM cteRange r
  INNER JOIN dataset d
  ON r.id=d.id
  AND d.timestamp BETWEEN r.start_ts AND r.end_ts
  GROUP BY r.id,r.start_ts
)
-- get the occurrences for each event sequence
SELECT id,event_sequence,COUNT(*) AS occurrences
FROM cte_Events
WHERE event_sequence='YourSequence' -- or get all sequence count without where
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...