У меня есть таблица с журналом действий, выполненных пользователем, типы действий - создание, подтверждение и отмена, что-то вроде этого:
action datetime user
create 2019-01-01 10:00:00 A
create 2019-01-05 10:00:00 A
confirm 2019-01-07 10:00:00 A
create 2019-01-07 10:00:00 A
cancel 2019-01-08 10:00:00 A
create 2019-01-09 10:00:00 A
create 2019-01-03 10:00:00 B
cancel 2019-01-08 10:00:00 B
create 2019-01-12 10:00:00 B
Итак, я хотел бы получить числодействия по типу, которые были сделаны пользователем перед созданием каждого действия, поэтому для данных до результата было бы так:
action datetime user create confirm cancel
create 2019-01-01 10:00:00 A 0 0 0
create 2019-01-05 10:00:00 A 1 0 0
create 2019-01-07 10:00:00 A 2 1 0
create 2019-01-09 10:00:00 A 3 1 1
create 2019-01-03 10:00:00 B 0 0 0
create 2019-01-12 10:00:00 B 1 0 1
я пытался настроить решение для this , но не могу получить различное количество по типу действия.
SELECT * FROM
( select *, count(1) OVER(PARTITION BY action, user ORDER BY datetime ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) create from `table` )
WHERE action = 'create' ORDER BY datetime LIMIT 20;
Есть идеи?
ОБНОВЛЕНИЕ: наконец получено 2 запроса,
Запрос 1:
select *
from (select t.*,
countif(action = 'create') over (PARTITION BY user order by datetime rows between unbounded preceding and 1 preceding) as num_create,
countif(action = 'confirm') over (PARTITION BY user order by datetime rows between unbounded preceding and 1 preceding) as num_confirm,
countif(action = 'cancel') over (PARTITION BY user order by datetime rows between unbounded preceding and 1 preceding) as num_cancel
from t
) t
where action = 'create' order by datetime;
Запрос 2:
select *
from (select t.*,
countif(action = 'create') over (PARTITION BY user order by datetime_diff(datetime(datetime), datetime('2000-01-01'), SECOND) range between unbounded preceding and 1 preceding) as num_create,
countif(action = 'confirm') over (PARTITION BY user order by datetime_diff(datetime(datetime), datetime('2000-01-01'), SECOND) range between unbounded preceding and 1 preceding) as num_confirm,
countif(action = 'cancel') over (PARTITION BY user order by datetime_diff(datetime(datetime), datetime('2000-01-01'), SECOND) range between unbounded preceding and 1 preceding) as num_cancel
from t
) t
where action = 'create' order by datetime;
Когда пользователь выполняет более 1 действия одновременно, Запрос 1 работает лучше.Спасибо !!
ОБНОВЛЕНИЕ 2: Окончательный запрос
#standardSQL
SELECT * FROM (
SELECT action, datetime, user,
COUNTIF(action = 'create') OVER(win) `create`,
COUNTIF(action = 'confirm') OVER(win) confirm,
COUNTIF(action = 'cancel') OVER(win) cancel
FROM `project.dataset.table`
WINDOW win AS (
PARTITION BY user
ORDER BY datetime, CASE action WHEN 'create' THEN 1 ELSE 0 END
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
)
)
WHERE action = 'create'
ORDER BY user, datetime