1、统计影音视频网站的常规指标,各种 TopN 指标

  1. 统计视频观看数 Top10
  2. 统计视频类别热度 Top10
  3. 统计出视频观看数最高的 20 个视频的所属类别以及类别包含 Top20 视频的个数
  4. 统计视频观看数 Top50 所关联视频的所属类别排序
  5. 统计每个类别中的视频热度 Top10,以 Music 为例
  6. 统计每个类别视频观看数 Top10
  7. 统计上传视频最多的用户 Top10 以及他们上传的视频观看次数在前 20 的视频

1.1、数据结构

  1. 视频表
字段 备注 详细描述
videoId 视频唯一 id(String) 11 位字符串
uploader 视频上传者(String) 上传视频的用户名 String
age 视频年龄(int) 视频在平台上的整数天
category 视频类别(Array<String>) 上传视频指定的视频分类
length 视频长度(Int) 整形数字标识的视频长度
views 观看次数(Int) 视频被浏览的次数
rate 视频评分(Double) 满分 5 分
Ratings 流量(Int) 视频的流量,整型数字
conments 评论数(Int) 一个视频的整数评论数
relatedId 相关视频 id(Array<String>) 相关视频的 id,最多 20 个
  1. 用户表
字段 备注 字段类型
uploader 上传者用户名 string
videos 上传视频数 int
friends 朋友数量 int

1.2、准备数据

创建最终表:video_ori,video_user_ori

  1. video_ori
video_ori
create table video_ori(
videoId string, uploader string, age int, category array<string>, length int, views int, rate float, ratings int, comments int,relatedId array<string>)
row format delimited fields terminated by "\t"
collection items terminated by "&"
stored as textfile;
  1. video_user_ori
create table video_user_ori(uploader string,videos int,friends int)
row format delimited
fields terminated by "\t"
stored as textfile;
load data local inpath "/opt/module/data/video" into table video_ori;
load data local inpath "/opt/module/user" into table video_user_ori;

测试数据

1.3、业务分析

1.3.1、统计视频观看数 Top10

思路:使用 order by 按照 views 字段做一个全局排序即可,同时我们设置只显示前 10条。

最终代码:

SELECT videoId,views
FROM video_ori
ORDER BY views DESC
LIMIT 10;

1.3.2、 统计视频类别热度 Top10

思路:

  1. 即统计每个类别有多少个视频,显示出包含视频最多的前 10 个类别。
  2. 我们需要按照类别 group by 聚合,然后 count 组内的 videoId 个数即可。
  3. 因为当前表结构为:一个视频对应一个或多个类别。所以如果要 group by 类别,需要先将类别进行列转行(展开),然后再进行 count 即可。
  4. 最后按照热度排序,显示前 10 条。
SELECT t1.category_name , COUNT(t1.videoId) hot
FROM
(
SELECT videoId, category_name
FROM video_ori
lateral VIEW explode(category) video_ori_tmp AS category_name
) t1
GROUP BY t1.category_name
ORDER BYhot
DESC
LIMIT 10

1.3.3、统计出视频观看数最高的 20 个视频的所属类别以及类别包含 Top20 视频的个数

思路:

  1. 先找到观看数最高的 20 个视频所属条目的所有信息,降序排列
  2. 把这 20 条信息中的 category 分裂出来(列转行)
  3. 最后查询视频分类名称和该分类下有多少个 Top20 的视频
SELECT
t2.category_name,COUNT(t2.videoId) video_sum
FROM
(
SELECTt1.videoId,category_name
FROM
(
SELECT videoId, views ,category
FROM video_ori
ORDER BY views
DESC
LIMIT 20
) t1
lateral VIEW explode(t1.category) t1_tmp AS category_name
) t2
GROUP BY t2.category_name

1.3.4、统计视频观看数 Top50 所关联视频的所属类别排序

SELECTt6.category_name,t6.video_sum,rank() over(ORDER BY t6.video_sum DESC ) rk
FROM
(
SELECTt5.category_name,COUNT(t5.relatedid_id) video_sum
FROM
(
SELECTt4.relatedid_id,category_name
FROM
(
SELECT t2.relatedid_id ,t3.category
FROM
(
SELECT relatedid_id
FROM
(
SELECT videoId, views,relatedid
FROM video_ori
ORDER BYviews
DESC
LIMIT 50
)t1
lateral VIEW explode(t1.relatedid) t1_tmp AS relatedid_id
)t2
JOIN gulivideo_orc t3
ON
t2.relatedid_id = t3.videoId
) t4
lateral VIEW explode(t4.category) t4_tmp AS category_name
) t5
GROUP BYt5.category_name
ORDER BY video_sum
DESC
) t6

1.3.5、统计每个类别中的视频热度 Top10,以 Music 为例

思路:

  1. 要想统计 Music 类别中的视频热度 Top10,需要先找到 Music 类别,那么就需要将category 展开,所以可以创建一张表用于存放 categoryId 展开的数据。
  2. 向 category 展开的表中插入数据。
  3. 统计对应类别(Music)中的视频热度。
SELECT t1.videoId, t1.views,t1.category_name
FROM
(
SELECTvideoId,views,category_name
FROM video_ori
lateral VIEW explode(category) video_ori_tmp AS category_name
)t1
WHERE t1.category_name = "Music"
ORDER BY t1.views
DESC
LIMIT 10

1.3.6、统计每个类别视频观看数 Top10

 t2.videoId,t2.views,t2.category_name,t2.rk
FROM
(
SELECT t1.videoId,t1.views,t1.category_name,rank() over(PARTITION BY t1.category_name ORDER BY t1.views DESC ) rk
FROM
(
SELECTvideoId,views,category_name
FROM video_orc
lateral VIEW explode(category) video_orc_tmp AS category_name
)t1
)t2
WHERE t2.rk <=10

1.3.7、统计上传视频最多的用户 Top10 以及他们上传的视频观看次数在前 20 的视频

思路:

  1. 求出上传视频最多的 10 个用户
  2. 关联 gulivideo_orc 表,求出这 10 个用户上传的所有的视频,按照观看数取前 20
 t2.videoId,t2.views,t2.uploader
FROM
(
SELECT uploader,videos
FROM video_user_orc
ORDER BY videos
DESC
LIMIT 10
) t1
JOIN video_orc t2
ON t1.uploader = t2.uploader
ORDER BY t2.views
DESC
LIMIT 20

2、常见的Hive 面试题

2.1、连续问题

2.1.1、需求:找出连续 3 天及以上减少碳排放量在 100 以上的用户

如下数据为蚂蚁森林中用户领取的减少碳排放量

id dt lowcarbon
1001 2021-12-12 123
1002 2021-12-12 45
1001 2021-12-13 43
1001 2021-12-13 45
1001 2021-12-13 23
1002 2021-12-14 45
1001 2021-12-14 230
1002 2021-12-15 45
1001 2021-12-15 23

找出连续 3 天及以上减少碳排放量在 100 以上的用户

2.1.2、解决方式

  1. 按照用户ID及时间字段分组,计算每个用户单日减少的碳排放量
selectid,dt,sum(lowcarbon) lowcarbon
from test1
group by id,dt
having lowcarbon>100;t1
1001    2021-12-12      123
1001    2021-12-13      111
1001    2021-12-14      230

等差数列法:两个等差数列如果等差相同,则相同位置的数据相减等到的结果相同

  1. 按照用户分组,同时按照时间排序,计算每条数据的Rank值
selectid,dt,lowcarbon,rank() over(partition by id order by dt) rk
from t1;t2
  1. 将每行数据中的日期减去Rank值
selectid,dt,lowcarbon,date_sub(dt,rk) flag
from t2;t3
  1. 按照用户及Flag分组,求每个组有多少条数据,并找出大于等于3条的数据
selectid,flag,count(*) ct
from t3
group by id,flag
having ct>=3;
  1. 最终HQL
selectid,flag,count(*) ct
from
(selectid,dt,lowcarbon,date_sub(dt,rk) flag
from
(selectid,dt,lowcarbon,rank() over(partition by id order by dt) rk
from
(selectid,dt,sum(lowcarbon) lowcarbon
from test1
group by id,dt
having lowcarbon>100)t1)t2)t3
group by id,flag
having ct>=3;

2.2、分组问题

2.2.1、需求:某个用户连续的访问记录如果时间间隔小于 60 秒,则分为同一个组

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

id ts(秒)
1001 17523641234
1001 17523641256
1002 17523641278
1001 17523641334
1002 17523641434
1001 17523641534
1001 17523641544
1002 17523641634
1001 17523641638
1001 17523641654

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

id ts(秒) group
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

2.2.2、解决方式

  1. 将上一行时间数据下移
    lead:领导
    lag:延迟
selectid,ts,lag(ts,1,0) over(partition by id order by ts) lagts
fromtest2;t11001    17523641234 0
1001    17523641256 17523641234
1001    17523641334 17523641256
1001    17523641534 17523641334
1001    17523641544 17523641534
1001    17523641638 17523641544
1001    17523641654 17523641638
1002    17523641278 0
1002    17523641434 17523641278
1002    17523641634 17523641434
  1. 将当前行时间数据减去上一行时间数据
selectid,ts,ts-lagts tsdiff
fromt1;t2selectid,ts,ts-lagts tsdiff
from(selectid,ts,lag(ts,1,0) over(partition by id order by ts) lagts
fromtest2)t1;t2
1001    17523641234 17523641234
1001    17523641256 22
1001    17523641334 78
1001    17523641534 200
1001    17523641544 10
1001    17523641638 94
1001    17523641654 16
1002    17523641278 17523641278
1002    17523641434 156
1002    17523641634 200
  1. 计算每个用户范围内从第一行到当前行tsdiff大于等于60的总个数(分组号)
selectid,ts,sum(if(tsdiff>=60,1,0)) over(partition by id order by ts) groupid
fromt2;
  1. 最终HQL
selectid,ts,sum(if(tsdiff>=60,1,0)) over(partition by id order by ts) groupid
from(selectid,ts,ts-lagts tsdiff
from(selectid,ts,lag(ts,1,0) over(partition by id order by ts) lagts
fromtest2)t1)t2;

2.3、间隔连续问题

2.3.1、需求:计算每个用户最大的连续登录天数,可以间隔一天。解释:如果一个用户在 1,3,5,6 登录游戏,则视为连续 6 天登录。

某游戏公司记录的用户每日登录数据

id dt
1001 2021-12-12
1002 2021-12-12
1001 2021-12-13
1001 2021-12-14
1001 2021-12-16
1002 2021-12-16
1001 2021-12-19
1002 2021-12-17
1001 2021-12-20

计算每个用户最大的连续登录天数,可以间隔一天。解释:如果一个用户在 1,3,5,6 登录游戏,则视为连续 6 天登录。

2.3.2、解决方式

思路:分组
1001 2021-12-12
1001 2021-12-13
1001 2021-12-14
1001 2021-12-16
1001 2021-12-19
1001 2021-12-20

  1. 将上一行时间数据下移
1001 2021-12-12  1970-01-01
1001    2021-12-13  2021-12-12
1001    2021-12-14  2021-12-13
1001    2021-12-16  2021-12-14
1001    2021-12-19  2021-12-16
1001    2021-12-20  2021-12-19selectid,dt,lag(dt,1,'1970-01-01') over(partition by id order by dt) lagdt
fromtest3;t1
  1. 将当前行时间减去上一行时间数据(datediff(dt1,dt2))
1001 2021-12-12  564564
1001    2021-12-13  1
1001    2021-12-14  1
1001    2021-12-16  2
1001    2021-12-19  3
1001    2021-12-20  1selectid,dt,datediff(dt,lagdt) flag
fromt1;t2
  1. 按照用户分组,同时按照时间排序,计算从第一行到当前行大于2的数据的总条数(sum(if(flag>2,1,0)))
1001 2021-12-12  1
1001    2021-12-13  1
1001    2021-12-14  1
1001    2021-12-16  1
1001    2021-12-19  2
1001    2021-12-20  2selectid,dt,sum(if(flag>2,1,0)) over(partition by id order by dt) flag
fromt2;t3
  1. 按照用户和flag分组,求最大时间减去最小时间并加上1
selectid,flag,datediff(max(dt),min(dt)) days
fromt3
group by id,flag;t4
  1. 取连续登录天数的最大值
selectid,max(days)+1
fromt4
group by id;
  1. 最终HQL
selectid,max(days)+1
from(selectid,flag,datediff(max(dt),min(dt)) days
from(selectid,dt,sum(if(flag>2,1,0)) over(partition by id order by dt) flag
from(selectid,dt,datediff(dt,lagdt) flag
from(selectid,dt,lag(dt,1,'1970-01-01') over(partition by id order by dt) lagdt
fromtest3)t1)t2)t3
group by id,flag)t4
group by id;

2.4、打折日期交叉问题

2.4.1、需求:计算每个品牌总的打折销售天数

如下为平台商品促销数据:字段为品牌,打折开始日期,打折结束日期

brand stt edt
oppo 2021-06-05 2021-06-09
oppo 2021-06-11 2021-06-21
vivo 2021-06-05 2021-06-15
vivo 2021-06-09 2021-06-21
redmi 2021-06-05 2021-06-21
redmi 2021-06-09 2021-06-15
redmi 2021-06-17 2021-06-26
huawei 2021-06-05 2021-06-26
huawei 2021-06-09 2021-06-15
huawei 2021-06-17 2021-06-21

计算每个品牌总的打折销售天数,注意其中的交叉日期,比如 vivo 品牌,第一次活动时间为 2021-06-05 到 2021-06-15,第二次活动时间为 2021-06-09 到 2021-06-21 其中 9 号到 15号为重复天数,只统计一次,即 vivo 总打折天数为 2021-06-05 到 2021-06-21 共计 17 天。

2.4.2、解决方式

  1. 将当前行以前的数据中最大的edt放置当前行
selectid,stt,edt,max(edt) over(partition by id order by stt rows between UNBOUNDED PRECEDING and 1 PRECEDING) maxEdt
from test4;t1
redmi   2021-06-05  2021-06-21  null
redmi   2021-06-09  2021-06-15  2021-06-21
redmi   2021-06-17  2021-06-26  2021-06-21
  1. 比较开始时间与移动下来的数据,如果开始时间大,则不需要操作,反之则需要将移动下来的数据加一替换当前行的开始时间,如果是第一行数据,maxEDT为null,则不需要操作
selectid,if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt,edt
from t1;t2redmi 2021-06-05  2021-06-21
redmi   2021-06-22  2021-06-15
redmi   2021-06-22  2021-06-26
  1. 将每行数据中的结束日期减去开始日期
selectid,datediff(edt,stt) days
fromt2;t3redmi  16
redmi   -4
redmi   4
  1. 按照品牌分组,计算每条数据加一的总和
selectid,sum(if(days>=0,days+1,0)) days
fromt3
group by id;redmi   22
  1. 最终HQL
selectid,sum(if(days>=0,days+1,0)) days
from(selectid,datediff(edt,stt) days
from(selectid,if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt,edt
from (selectid,stt,edt,max(edt) over(partition by id order by stt rows between UNBOUNDED PRECEDING and 1 PRECEDING) maxEdt
from test4)t1)t2)t3
group by id;

2.5、同时在线问题

2.5.1、需求

如下为某直播平台主播开播及关播时间,根据该数据计算出平台最高峰同时在线的主播人数。

id stt edt
1001 2021-06-14 12:12:12 2021-06-14 18:12:12
1003 2021-06-14 13:12:12 2021-06-14 16:12:12
1004 2021-06-14 13:15:12 2021-06-14 20:12:12
1002 2021-06-14 15:12:12 2021-06-14 16:12:12
1005 2021-06-14 15:18:12 2021-06-14 20:12:12
1001 2021-06-14 20:12:12 2021-06-14 23:12:12
1006 2021-06-14 21:12:12 2021-06-14 23:15:12
1007 2021-06-14 22:12:12 2021-06-14 23:10:12

2.5.2、解决方式

  1. 对数据分类,在开始数据后添加正1,表示有主播上线,同时在关播数据后添加-1,表示有主播下线
select id,stt dt,1 p from test5
union
select id,edt dt,-1 p from test5;t11001 2021-06-14 12:12:12 1
1001    2021-06-14 18:12:12 -1
1001    2021-06-14 20:12:12 1
1001    2021-06-14 23:12:12 -1
1002    2021-06-14 15:12:12 1
1002    2021-06-14 16:12:12 -1
1003    2021-06-14 13:12:12 1
1003    2021-06-14 16:12:12 -1
1004    2021-06-14 13:15:12 1
1004    2021-06-14 20:12:12 -1
1005    2021-06-14 15:18:12 1
1005    2021-06-14 20:12:12 -1
1006    2021-06-14 21:12:12 1
1006    2021-06-14 23:15:12 -1
1007    2021-06-14 22:12:12 1
1007    2021-06-14 23:10:12 -1
  1. 按照时间排序,计算累加人数
selectid,dt,sum(p) over(order by dt) sum_p
from(select id,stt dt,1 p from test5
union
select id,edt dt,-1 p from test5)t1;t2
  1. 找出同时在线人数最大值
selectmax(sum_p)
from(selectid,dt,sum(p) over(order by dt) sum_p
from(select id,stt dt,1 p from test5
union
select id,edt dt,-1 p from test5)t1)t2;

HIVE常见面试题以及实战练习(六)相关推荐

  1. Hive常见面试题汇总

    一.Hive架构介绍. 遇到这类问题,可以灵活的去回答,比如可以结合平时使用hive的经验作答,也可以结合下图从数据的读入.解析.元数据的管理,数据的存储等角度回答: 1.Meta Store Met ...

  2. “约见”面试官系列之常见面试题第三十六篇之CSS常见兼容性问题及解决方案(建议收藏)

    CSS常见兼容性问题及解决方案: 1. 上下margin重合问题: 问题描述:相邻的margin-left和margin-right是不会重合的,但是相邻的块级元素margin-top 和margin ...

  3. hive 常见面试题

    (笔者自己做记录) 1.Hive内外部表的区别 删除表是否影响外部数据 2.Hive如何做到权限管理 hive下可以修改配置后创建用户管理,但是仅仅是为了防止误操而已,如果要真的为了安全操作建议使用 ...

  4. “约见”面试官系列之常见面试题之第九十六篇之active-class是谁的属性(建议收藏)

    active-class 属于vue-router的样式方法,当router-link标签被点击时将会应用这个样式 一.首先,active-class是什么,active-class是vue-rout ...

  5. 【JAVA秒会技术之秒杀面试官】JavaEE常见面试题(六)

    [前言]别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得游手好闲,和你一样会抱怨,而只有你自己相信这些都是真的,最后,也只有你一个人继续不思进取 --   [下载]个人结合诸多资料 ...

  6. java ee笔试题_【JAVA秒会技术之秒杀面试官】JavaEE常见面试题(六)

    [前言]别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得游手好闲,和你一样会抱怨,而只有你自己相信这些都是真的,最后,也只有你一个人继续不思进取 -- [下载]个人结合诸多资料,总 ...

  7. [Java面试]六:常见面试题之设计模式

    我的博客首页:http://blog.csdn.net/m0_37116405 我的GitHub首页:https://github.com/KissLouis 设计模式六大原则 开闭原则:对扩展开放, ...

  8. 常见面试题整理--操作系统篇(每位开发者必备)

    这两日整理了很多编程方面的资料:教学视频.书籍资源以及实战项目全部放在了百度网盘里,资源的目录以及获取方式都放在了文末的图上,你可以直接翻至文末查看. 有过面试经历的人都知道操作系统是面试官必问的几大 ...

  9. 3w字 长文干货!100 道 Linux 常见面试题

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 本文一共 3W + 字,分别从 Linux概述.磁盘.目录.文件.安全.语法级.实战.文件管理 ...

最新文章

  1. Django:永别了pycrypto库~
  2. 大型高并发高负载网站的系统架构(转)
  3. Java线程池Executor框架
  4. lunbuntu install mysql5.7
  5. Java 8 Lambda演练
  6. 为什么要free释放内存_为什么在Free Code Camp上列出一份工作要花1,000美元?
  7. LeetCode 672. 灯泡开关 Ⅱ(枚举)
  8. java写pdf_java写出PDF
  9. 存储相关知识-DAS/SAN/NAS
  10. STM32CubeMX使用(七)之通用定时器和系统定时器
  11. 广州大彩串口屏与STM32F407通讯
  12. 网络工程师有什么发展?
  13. SQLSERVER的中文排序规则
  14. 滴滴AI负责人叶杰平:你的每一次出行,都已有AI落地的助力
  15. 零中频接收机频率转换图_相干光接收机的相关问题
  16. c语言检测邮箱地址,C语言实现电子邮件地址验证程序
  17. 视觉SLAM十四讲-第九讲例程运行出错
  18. 游戏服务器主程白皮书-序言
  19. 15数字华容道解法 图解_数字华容道解法图解 数字华容道玩法介绍
  20. JavaRobot模拟键盘输入方法

热门文章

  1. echarts 多图表的自适应窗口大小,自动缩放
  2. 如何构建公司级的数据指标体系
  3. 如何建立免费企业邮箱(腾讯、网易)
  4. 计算机无误的英语,“开电脑”的英语正确表示是哪个?说错了就尴尬
  5. 【笔记】 node.js - 开启本地服务器,返回json数据
  6. 窗口无故失去焦点解决方案
  7. cron表达式实现40分钟执行一次的解决方案
  8. 逻辑回归三部曲——逻辑回归项目实战(信贷数据+Python代码实现)
  9. c语言数组出界,C语言编游戏如何判断物体是否出界啊?
  10. opencv读图的坐标系转换问题