SQL中countinues状态的聚合
Posted
技术标签:
【中文标题】SQL中countinues状态的聚合【英文标题】:Aggregation on countinues status in SQL 【发布时间】:2020-05-08 09:43:16 【问题描述】:我正在处理一些包含play
和end
的播放状态日志数据。在游戏过程中,客户端会多次报告play
,但当出现end
时,表示游戏结束,比如
user_id status timestamp
a play xxx
a play xxx
a play xxx
a end xxx
b play xxx
b end xxx
c play xxx
c play xxx
c end xxx
a play xxx
a play xxx
a end xxx
a play xxx
a end xxx
现在,我可以使用row_number()
来计算user_id
的数量与超过2 个play
状态的游戏类似:
# I realize this is a wrong query...
select count(distinct user_id) as cnt_uid
(select
user_id,status,timestamp,
row_number() over (partition by user_id, status, order by timestamp) as rn
from tableA) a
where rn>=2
但是如果我需要计算超过 2 个play
状态的游戏数量(例如:user A
有 2 个游戏超过 2 个play
状态,user C
有 1 个),该怎么做?任何帮助表示赞赏。
*PS:预期结果只是一些游戏的状态超过 2 个play
,对于上面给出的数据,结果是3
。
【问题讨论】:
如果在 hive 中可用,您可以使用 DENSE_RANK() @DigvijayS 感谢您的回复。我在Hive
中尝试了dense_rank() over (order by status)
,我认为结果等同于user_id
...如果我没有以正确的方式使用它,请随时告诉我....
您能否通过编辑您的帖子添加预期输出。
嗨@DigvijayS 我刚刚修改了帖子,实际上,这种情况下的预期输出只是一个数字:3
【参考方案1】:
您可以使用status = 'end'
的累积总和来定义“游戏”。然后再聚合再聚合:
select user_id, count(*) as games_with_2+_plays
from (select user_id, grp, count(*) as num_plays
from (select t.*,
sum(case when status = 'end' then 1 else 0 end) over (partition by user_id order by timestamp) as grp
from t
) t
where status = 'play'
group by user_id, grp
)
where num_plays >= 2
group by user_id;
【讨论】:
感谢您的精彩回答!!!在您的查询中,status = 'end'
被删除,这是可行的。如果我需要每场比赛的时间间隔(时间间隔=end
的时间戳-每场比赛的第一个play
的时间戳),如何计算?
@user2894829 。 . .你会做类似min(timestamp)
和max(timestamp)
之间的区别。以上是关于SQL中countinues状态的聚合的主要内容,如果未能解决你的问题,请参考以下文章