首页 技术 正文
技术 2022年11月15日
0 收藏 520 点赞 2,819 浏览 1028 个字

昨天群上有人发个阿里的面试题,题目描述大概如下:

数据源:用户登录表,只有俩个字段,uid和dt

试用HQL抽取出连续登录了K天的用户uid

第一个想法就是直接用一个UDF解决,按uid分组,把dt收集起来然后在UDF里面判断是否满足条件

SELECT
uid,
isExist(collect_set(dt), k) flag
FROM
table_name
GROUP BY
uid
HAVING
flag = 1;

其中isExist的逻辑是判断collect_set中是否存在k个连续的值

这种方法简单明了,但是需要额外的写一个UDF,对于不懂JAVA的来说确实比较麻烦

今天群里有个神人给出了一种新的解决思路,十分完美的解决了,下面是具体代码

SELECT
uid, MAX(dt) - MIN(dt) diff, COLLECT_set (dt)
FROM
(SELECT
a.uid, a.dt, dt - rn num
FROM
(SELECT
uid, dt, row_number () over (PARTITION BY uid
ORDER BY dt) rn
FROM
table_name
GROUP BY uid, dt) a) a
GROUP BY uid, num

该思路首先利用窗口函数以uid分组然后按照dt排序给出每个dt在排序中的位置,然后用求出dt与位置的差(记为num)

最后按照uid和num做一个聚合,容易发现同一个num组内的dt是连续的值

然后直接计数(count(*))就可以得出结果了

上面的代码只是为了更加方便看到输出的结果正确性,输出结果如下:

UID        DIFF    DT_ARRAY
1043736 3.0 {20140815 20140814 20140813 20140812}
1043736 0.0 {20140818}
1043736 1.0 {20140821 20140820}
1043844 0.0 {20140814}
1044090 1.0 {20140812 20140811}
1044090 2.0 {20140816 20140815 20140817}
1044090 0.0 {20140821}
1044264 0.0 {20140810}
1044264 3.0 {20140815 20140814 20140813 20140812}
1044264 5.0 {20140821 20140820 20140822 20140819 20140817 20140818}

结果中uid = 1043736 的一共登录了7天,其中可以拆分成三个连续的登录模块,分别是连续登录1天、2天和4天

    
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,995
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,509
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,352
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,136
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,769
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,847