Использование LEAD в BigQuery

Предположим, что моя структура таблицы такова

введите здесь описание изображения

Я планирую сгруппировать его по (USER и SEQUENCE) и получить временную метку LEAD для следующей последовательности. Вот результат, который я ищу

введите здесь описание изображения

Могу ли я решить эту проблему без JOIN, используя функцию LEAD, если это возможно?


person phaigeim    schedule 13.12.2017    source источник


Ответы (2)


Ниже приведен стандартный SQL BigQuery.

Я представлю два варианта - с использованием JOIN (просто для того, чтобы подтвердить, что я правильно понял/обратил ожидаемую логику), а затем версию без JOIN (обратите внимание, что я использую ts в качестве имени поля вместо timestamp)

Использование ПРИСОЕДИНЯЙТЕСЬ

#standardSQL
SELECT a.user, a.sequence, MIN(b.ts) ts 
FROM (
  SELECT user, sequence, MAX(ts) AS max_ts
  FROM `project.dataset.table`
  GROUP BY user, sequence
) a
LEFT JOIN `project.dataset.table` b
ON a.user = b.user AND b.sequence = a.sequence + 1
WHERE a.max_ts <= IFNULL(b.ts, a.max_ts)
GROUP BY user, sequence
-- ORDER BY user, sequence

Версия без JOIN

#standardSQL
SELECT
  user, sequence, 
  (
    SELECT ts FROM UNNEST(arr_ts) ts 
    WHERE max_ts < ts ORDER BY ts LIMIT 1
  ) ts
FROM (
  SELECT
    user, sequence, max_ts,
    LEAD(arr_ts) OVER (PARTITION BY user ORDER BY sequence) arr_ts
  FROM (
  SELECT 
      user, sequence, MAX(ts) max_ts, 
      ARRAY_AGG(ts ORDER BY ts) arr_ts
    FROM `project.dataset.table`
    GROUP BY user, sequence
  )
)
-- ORDER BY user, sequence   

Обе вышеуказанные версии могут быть протестированы / воспроизведены с использованием приведенных ниже фиктивных данных.

WITH `project.dataset.table` AS (
  SELECT 'user1' user, 2 sequence, 'T1' ts UNION ALL
  SELECT 'user1', 2, 'T2' UNION ALL
  SELECT 'user1', 1, 'T3' UNION ALL
  SELECT 'user1', 1, 'T4' UNION ALL
  SELECT 'user1', 3, 'T5' UNION ALL
  SELECT 'user1', 2, 'T6' UNION ALL
  SELECT 'user1', 3, 'T7' UNION ALL
  SELECT 'user1', 3, 'T8' 
)   

и оба возвращаются ниже результата

user    sequence    ts   
user1   1           T6   
user1   2           T7   
user1   3           null     
person Mikhail Berlyant    schedule 13.12.2017
comment
Спасибо за то, что поделился этим. Это Бриллиант. Не могли бы вы проверить stackoverflow.com/q/47819258/3879625 - person phaigeim; 14.12.2017
comment
Не могли бы вы помочь мне здесь stackoverflow.com/questions/51153124 / - person phaigeim; 03.07.2018
comment
@phaigeim - конечно. ответил. можешь проверить :о) - person Mikhail Berlyant; 03.07.2018

Не уверен насчет bigquery, но в общем SQL это будет написано так:

select user, sequence, LEAD (max_timestamp,1) OVER (PARTITION BY user ORDER BY sequence) as timestamp
from (
    select user, sequence, max(timestamp) as max_timestamp
    from table
    group by user, sequence) q1;

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

Изменить: Да, забудьте об этом ответе, недостаточно внимательно относитесь к требуемому выводу. Михаил правильно понял!

person Edgars T.    schedule 13.12.2017
comment
@phaigeim - я не думаю, что это правильный ответ - по крайней мере, он возвращает не то, что ожидается в вопросе - person Mikhail Berlyant; 13.12.2017
comment
@Edgars Не могли бы вы проверить это stackoverflow.com/questions/ 51153124/ - person phaigeim; 03.07.2018