【问题标题】:Hive rolling sum of data over dateHive 滚动数据的日期总和
【发布时间】:2018-09-23 10:18:09
【问题描述】:

我正在研究 Hive,并且面临滚动计数的问题。我正在处理的示例数据如下所示:

我期待的输出如下所示:

我尝试使用以下查询,但它没有返回滚动计数:

select event_dt,status, count(distinct account) from
(select *, row_number() over (partition by account order by event_dt 
desc) 
as rnum from table.A 
where event_dt between '2018-05-02' and '2018-05-04') x where rnum =1 
group by event_dt, status;

如果有人解决了类似的问题,请帮助我。

【问题讨论】:

  • 实际上,我无法弄清楚这些汇总数字是如何从这些数据中得出的。
  • 嗨戈登,基本上如果你看到日期 05/02 有 A1 A2 和 A3 注册但 A2 也移动到活动状态,这意味着 A1 和 A3 只注册但 A2 是活动的所以注册账户计数为 A1 & A3 = 2,A2 即 1 个帐户显示为活动状态。第二天添加了 3 个帐户 A4、5、6,A4 在同一日期处于活动状态,这意味着 1 被添加到活动状态但 A2 被暂停,所以我们从活动状态减少一个并添加到暂停,所以 A5、A6、A1、A3 仍然存在在已注册的 A4 中处于活动状态,而 A2 处于暂停状态。
  • 。 .你的描述有问题。日期都是相同的,没有其他列指定顺序。你怎么知道动作的顺序?记住:SQL 表没有顺序,所以这些信息必须在一个列中。
  • 哦,好吧..我很抱歉我是从另一个表生成这些数据,并且我转换了迄今为止的时间戳。我错过了在上面的问题中提到这些信息。那么如果我们有一个时间戳,解决方案会是什么样子呢?

标签: sql hive hiveql


【解决方案1】:

您似乎只想要条件聚合:

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 不(还?)支持 lag() 中的 ignore nulls 选项。

【讨论】:

  • 非常感谢您的意见,它们非常有帮助,我已经找到了使用它们的解决方案。
猜你喜欢
  • 2021-05-27
  • 2020-05-27
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2017-07-04
相关资源
最近更新 更多