Вы, похоже, просто хотите условную агрегацию:
select event_dt,
sum(case when status = 'Registered' then 1 else 0 end) as registered,
sum(case when status = 'active_acct' then 1 else 0 end) as active_acct,
sum(case when status = 'suspended' then 1 else 0 end) as suspended,
sum(case when status = 'reactive' then 1 else 0 end) as reactive
from table.A
group by event_dt
order by event_dt;
РЕДАКТИРОВАТЬ:
Это сложная проблема.Решение, которое я придумала, создает перекрестное произведение дат и пользователей, а затем вычисляет самый последний статус на каждую дату.
Итак:
select a.event_dt,
sum(case when aa.status = 'Registered' then 1 else 0 end) as registered,
sum(case when aa.status = 'active_acct' then 1 else 0 end) as active_acct,
sum(case when aa.status = 'suspended' then 1 else 0 end) as suspended,
sum(case when aa.status = 'reactive' then 1 else 0 end) as reactive
from (select d.event_dt, ac.account, a.status,
max(case when a.status is not null then a.timestamp end) over (partition by ac.account order by d.event_dt) as last_status_timestamp
from (select distinct event_dt from table.A) d cross join
(select distinct account from table.A) ac left join
(select a.*,
row_number() over (partition by account, event_dt order by timestamp desc) as seqnum
from table.A a
) a
on a.event_dt = d.event_dt and
a.account = ac.account and
a.seqnum = 1 -- get the last one on the date
) a left join
table.A aa
on aa.timestamp = a.last_status_timestamp and
aa.account = a.account
group by d.event_dt
order by d.event_dt;
Что это делаетсоздает производную таблицу со строками для всех учетных записей и дат.Он имеет статус в определенные дни, но не во все дни.
Совокупный максимум для last_status_timestamp
вычисляет самую последнюю временную метку, которая имеет действительный статус.Затем он присоединяется к таблице, чтобы получить статус на эту дату.Вуаля!Это состояние, используемое для условного агрегирования.
Совокупный максимум и объединение - это обходной путь, потому что Hive (пока?) Не поддерживает параметр ignore nulls
в lag()
.