as tp, from login union all select user_id, ts, 'logout' as tp, from logout ) select user_id, min(if(tp='login', ts, NULL)) as login_ts, max(if(tp='logout', ts, NULL)) as logout_ts, from ( select *, sum(is_start) over ( partition by user_id order by ts rows between unbounded preceding and current row ) as session_no, from ( select *, if (lag(tp) over (partition by user_id order by ts) = 'logout' and tp = 'login', 1, 0) as is_start, from event_log ) ) group by user_id, session_no having login_ts is not NULL -- 最初のログがログアウトを除外 order by user_id, login_ts -- debug 2つのイベントログを1つにつなげる ログアウト→ログイン時にフラグ1を立てる フラグの累積和を取りログインセッション番号を作る 単にmin(ts)とmax(ts)だと集計期間の都合で ログインがないケースで問題となる