Hive实战案例(一):利用row_number()计算连续值

Hive实战案例(一):利用row_number()计算连续值

题目一
题目描述

求出连续7天登录的用户

数据内容

1 2019-07-11 1
1 2019-07-12 1
1 2019-07-13 1
1 2019-07-14 1
1 2019-07-15 1
1 2019-07-16 1
1 2019-07-17 1
1 2019-07-18 1
2 2019-07-11 1
2 2019-07-12 1
2 2019-07-13 0
2 2019-07-14 1
2 2019-07-15 1
2 2019-07-16 0
2 2019-07-17 1
2 2019-07-18 0
3 2019-07-11 1
3 2019-07-12 1
3 2019-07-13 1
3 2019-07-14 0
3 2019-07-15 1
3 2019-07-16 1
3 2019-07-17 1
3 2019-07-18 1
准备工作

– 建表语句
create table ulogin(
uid int,
dt date,
status int
)
row format delimited fields terminated by ’ ';

– 加载数据
load data local inpath ‘/home/hadoop/data/ulogin.dat’ into
table ulogin;

解题思路

连续值的求解,面试中常见的问题。这也是同一类,基本都可按照以下思路进行:
1、使用 row_number 在组内给数据编号(rownum)
2、某个值 - rownum = gid,得到结果可以作为后面分组计算的依据
3、根据求得的gid,作为分组条件,求最终结果

要判断数据在某个字段上连续,则可以利用row_number()函数进行处理。因为该函数对每行数据打上连续的行坐标,此时利用待判断的字段值与行号进行相减,这样如果是连续值-连续值,则它们的差值是相等的。比如:

10 - 1 = 9
11 - 2 = 9
12 -3 = 9
....

此时,如果要计算题目中连续7天登陆的用户,即可以利用id与该差值字段共同作为分组的key,然后利用聚合函数 count(*) 来统计组内个数,如果等于7的话,就说明该用户连续登陆了七天。

代码示例

select uid, count(*) logincount
    from (select uid, dt,
                            date_sub(dt, row_number() over (partition by
uid order by dt)) gid
                    from ulogin
                where status=1) t1
group by uid, gid
having logincount>=7;

题目二
题目描述

找出下列数据中全部夺得3连贯的队伍

数据内容
team,year
活塞,1990
公牛,1991
公牛,1992
公牛,1993
火箭,1994
火箭,1995
公牛,1996
公牛,1997
公牛,1998
马刺,1999
湖人,2000
湖人,2001
湖人,2002
马刺,2003
活塞,2004
马刺,2005
热火,2006
马刺,2007
凯尔特人,2008
湖人,2009
湖人,2010
准备工作

-- 创建数据表
create table t1(
team string,
year int
)row format delimited fields terminated by ',';

-- 加载本地数据
load data local inpath "/root/data/t1.dat" into table t1;
解题思路

解题思路同上。由于要找到三连冠的队伍,即同样可以转换成对于连续值求解的问题。利用row_number() 函数对行标号,然后利用年份值与行号进行相减,这样,如果几条连续年份的记录相减后得到的值是相等的。因此就可以利用row_number()函数,其中利用over函数进行开窗, 按照team字段进行分区,按照year字段进行排序。然后将year列与row_number()得到的值相减,这样的话,如果在数据上时间连续,则相减后得到的差值应该是相等的。因此就可以对得到的结果,按照team字段和差值进行分组,并利用聚合函数count(*)计算组内数据的个数,如果个数为3,说明该队伍就是3连贯的队伍

代码示例

with tmp as (
    select team, year, year - row_number() over(partition by team order by year) num
    from t1
)

select team
from tmp
group by team, num
having count(*)=3
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JermeryBesian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值