BigQuery SQL для отслеживания времени задержки в точке интереса по данным о местоположении с несколькими остановками - PullRequest
1 голос
/ 23 января 2020

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

Вот подмножество данных:

ID, Location, UnixTimestamp
IDABCDE,"Place_3",2018-03-16 07:42:39
IDABCDE,"Place_2",2018-03-16 12:50:22
IDABCDE,"Place_2",2018-03-16 12:50:23
IDABCDE,"Place_2",2018-03-16 12:50:28
IDABCDE,"Place_1",2018-03-16 12:58:27
IDABCDE,"Place_2",2018-03-16 12:58:27
IDABCDE,"Place_2",2018-03-16 13:02:45
IDABCDE,"Place_1",2018-03-16 13:02:45
IDABCDE,"Place_2",2018-03-16 14:05:47
IDABCDE,"Place_2",2018-03-16 14:05:54
IDABCDE,"Place_2",2018-03-16 14:05:57
IDABCDE,"Place_2",2018-03-16 14:10:19
IDABCDE,"Place_2",2018-03-16 14:11:13
IDABCDE,"Place_1",2018-03-16 14:11:13
IDABCDE,"Place_3",2018-03-16 14:13:03
IDABCDE,"Place_3",2018-03-16 14:16:01
IDABCDE,"Place_3",2018-03-16 14:16:01
IDABCDE,"Place_3",2018-03-16 14:16:08
IDABCDE,"Place_3",2018-03-16 14:16:14
IDABCDE,"Place_3",2018-03-16 14:17:08
IDABCDE,"Place_3",2018-03-16 14:17:31
IDABCDE,"Place_3",2018-03-16 14:18:07
IDABCDE,"Place_3",2018-03-16 14:18:07
IDABCDE,"Place_3",2018-03-16 14:18:07
IDABCDE,"Place_3",2018-03-16 15:02:04
IDABCDE,"Place_3",2018-03-16 15:02:04
IDABCDE,"Place_3",2018-03-16 15:02:19
IDABCDE,"Place_3",2018-03-16 15:03:17
IDABCDE,"Place_3",2018-03-16 15:03:17
IDABCDE,"Place_2",2018-03-16 15:05:34

Запрос должен возвращать продолжительность для группировки значений для первого экземпляра Места 2, 0 для Места 1 (только одно наблюдение ), вычислите второе время задержки для места_2, 0 для второго посещения места_1, затем время задержки для места_3.

Я пробовал варианты на следующем:

SELECT ID, location, 
min(Unix_Timestamp) as first_observation, max(Unix_Timestamp) as last_observation,
TIMESTAMP_DIFF(max(Unix_Timestamp),min(Unix_Timestamp), minute) as time_in_location
FROM `table_name`
GROUP BY ID, location 

Возвращает разницу во времени между первым и последним значениями каждого места (это то, что запрашивает запрос, но не это не совсем то, что мне нужно).

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

Любое понимание, которое у вас есть, очень ценится. Спасибо.

1 Ответ

1 голос
/ 23 января 2020

Это код сегментации, который вы ищете:

SELECT *, SUM(x) OVER(PARTITION BY id ORDER BY unix_timestamp, location) segmentId
FROM (
  SELECT *, IF(LAG(location) OVER(PARTITION BY id ORDER BY unix_timestamp, location)=location,0,1) x
  FROM data
)

При этом ваш существующий код будет работать, как и ожидалось, с минимальными изменениями: GROUP BY ..., segment_id.

WITH data AS (
SELECT REGEXP_EXTRACT(x, r'([^\,]*),') id
, REGEXP_EXTRACT(x, r',([^\,]*),') location
, TIMESTAMP(REGEXP_EXTRACT(x, r',([^\,]*)$')) unix_timestamp
FROM UNNEST(SPLIT("""IDABCDE,"Place_3",2018-03-16 07:42:39
IDABCDE,"Place_2",2018-03-16 12:50:22
IDABCDE,"Place_2",2018-03-16 12:50:23
IDABCDE,"Place_2",2018-03-16 12:50:28
IDABCDE,"Place_1",2018-03-16 12:58:27
IDABCDE,"Place_2",2018-03-16 12:58:27
IDABCDE,"Place_2",2018-03-16 13:02:45
IDABCDE,"Place_1",2018-03-16 13:02:45
IDABCDE,"Place_2",2018-03-16 14:05:47
IDABCDE,"Place_2",2018-03-16 14:05:54
IDABCDE,"Place_2",2018-03-16 14:05:57
IDABCDE,"Place_2",2018-03-16 14:10:19
IDABCDE,"Place_2",2018-03-16 14:11:13
IDABCDE,"Place_1",2018-03-16 14:11:13
IDABCDE,"Place_3",2018-03-16 14:13:03
IDABCDE,"Place_3",2018-03-16 14:16:01
IDABCDE,"Place_3",2018-03-16 14:16:01
IDABCDE,"Place_3",2018-03-16 14:16:08
IDABCDE,"Place_3",2018-03-16 14:16:14
IDABCDE,"Place_3",2018-03-16 14:17:08
IDABCDE,"Place_3",2018-03-16 14:17:31
IDABCDE,"Place_3",2018-03-16 14:18:07
IDABCDE,"Place_3",2018-03-16 14:18:07
IDABCDE,"Place_3",2018-03-16 14:18:07
IDABCDE,"Place_3",2018-03-16 15:02:04
IDABCDE,"Place_3",2018-03-16 15:02:04
IDABCDE,"Place_3",2018-03-16 15:02:19
IDABCDE,"Place_3",2018-03-16 15:03:17
IDABCDE,"Place_3",2018-03-16 15:03:17
IDABCDE,"Place_2",2018-03-16 15:05:34""", '\n')) x
)

, dataprep AS (
  SELECT *, SUM(x) OVER(ORDER BY unix_timestamp, location) segmentId
  FROM (
    SELECT *, IF(LAG(location) OVER(ORDER BY unix_timestamp, location)=location,0,1) x
    FROM data
  )
)

SELECT
  ID, location, 
  min(Unix_Timestamp) as first_observation, max(Unix_Timestamp) as last_observation,
  TIMESTAMP_DIFF(max(Unix_Timestamp),min(Unix_Timestamp), second) as time_in_location
  , COUNT(*) steps
FROM dataprep
GROUP BY ID, location, segmentId

enter image description here

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