ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL之重分组算法实践【累加器思想】--Hivesql面试题31

2021-07-17 17:01:59  阅读:181  来源: 互联网

标签:面试题 -- visit 累加器 ts id SQL 1002 1001


目录

0 需求分析

1 数据准备

2 数据分析

3 小结


0 需求分析

如下为电商公司用户访问时间数据

idts
100117523641234
100117523641256
100217523641278
100117523641334
100217523641434
100117523641534
100117523641544
100217523641634
100117523641638
100117523641654

某个用户相邻的访问记录如果时间间隔小于 60 秒,则分为同一个组,结果为:

idtsgroupid
1001175236412341
1001175236412561
1001175236413342
1001175236415343
1001175236415443
1001175236416384
1001175236416544
1002175236412781
1002175236414342
1002175236416343

 1 数据准备

(1)数据

vim visit.txt

1001	17523641234
1001	17523641256
1002	17523641278
1001	17523641334
1002	17523641434
1001	17523641534
1001	17523641544
1002	17523641634
1001	17523641638
1001	17523641654

(2)建表

create table if not exists visit(
 
id string,
ts string
 
)
 
row format delimited
fields terminated by '\t'
 
;

(3)加载数据

load data local inpath "/home/centos/dan_test/visit.txt" into table visit;

(4) 查询数据

hive> select * from visit;
OK
1001	17523641234
1001	17523641256
1002	17523641278
1001	17523641334
1002	17523641434
1001	17523641534
1001	17523641544
1002	17523641634
1001	17523641638
1001	17523641654
Time taken: 1.77 seconds, Fetched: 10 row(s)

2 数据分析

目标:某个用户相邻记录如果时间间隔小于 60 秒,则分为同一个组。

如果不用sql,正常的思路就是按ts排序,将相邻的两天记录先相减得到的差值先进行观察找规律

用SQL实现上述思路,具体SQL如下:

select
    id,
    ts,
    ts-lag(ts,1,0) over(partition by id order by ts)
from visit

计算结果如下:

--------------------------------------------------------------------------------
OK
1001	17523641234	1.7523641234E10
1001	17523641256	22.0
1001	17523641334	78.0
1001	17523641534	200.0
1001	17523641544	10.0
1001	17523641638	94.0
1001	17523641654	16.0
1002	17523641278	1.7523641278E10
1002	17523641434	156.0
1002	17523641634	200.0
Time taken: 10.196 seconds, Fetched: 10 row(s)

我们按照上述的中间结果手动按照题意进行分组,要求的是相邻时间间隔小于60的被分成一组,手动分组如下:

 我们在手动进行分组的过程中,发现这样一个规律当遇到时间间隔大于60的数据进行加一操作,也就是我们通常所说的累加器思想,类似于流式数据(按时间序列进行排序后)进入累加器中当满足某种条件后(或发生了某种变化后)计数器就加1,这样就把连续的时序数据就区分开了,因为我需要的是把每一次变化都分别放在一个组里,不变的放一个组里,我需要的是观察截止当前发生变化了的次数,那么计数器里面保留的就是截止当前发生变化的次数(可以理解为截止当前在线人数),如果按照这种思想去分组,那么中间没变化的会发生持续一段时间,如果有变化,会显示新增人数,这样不变的数据就被区分出来。

根据上述分析,我们知道累加的实现在SQL中就是sum() over(),于是我们最终的SQL如下:


select id,
       ts,
       sum(if(ts_diff>=60,1,0)) over(partition by id order by ts) as groupid
from(
select
    id,
    ts,
    ts-lag(ts,1,0) over(partition by id order by ts) as ts_diff
from visit
)t

计算结果如下:

--------------------------------------------------------------------------------
OK
1001	17523641234	1
1001	17523641256	1
1001	17523641334	2
1001	17523641534	3
1001	17523641544	3
1001	17523641638	4
1001	17523641654	4
1002	17523641278	1
1002	17523641434	2
1002	17523641634	3
Time taken: 23.026 seconds, Fetched: 10 row(s)

3 小结

本文总结了一种重新分组的方法,从不同的角度来认识该算法,该方法实际上在业务中经常被用到,之前我们讲到的分桶重排序算法等实际上和这个是类似的,只不过本文从不同的角度来解释该算法,让读者能够更深刻的认识该算法,从而更好的应用实践中,解决实际问题。

标签:面试题,--,visit,累加器,ts,id,SQL,1002,1001
来源: https://blog.csdn.net/godlovedaniel/article/details/118856415

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有