最近在深入了解Hive,尚硅谷的这5道题很经典,有引导意义,分步解题也很有用,故记录之,方便回看

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

建表

create table mayi
(id        int,dt        string,lowcarbon int
)row format delimitedfields terminated by '\t';
load data local inpath "/home/hadoop/test/mayi.txt" into table mayi;
select *
from mayi;
--1)求出每日lowcarbon在100以上的用户记录
select id, dt, sum(lowcarbon) lowcarbon
from mayi
group by id, dt
having lowcarbon > 100;
-- t1
-- 2)等差数列法
-- 两个等差数据如果等差相同,则相同位置的数据相减得到的相同
-- 按照用户分组,同时按照时间排序,计算每条数据的Rank
select id,dt,lowcarbon,rank() over (partition by id order by dt) rk
from t1;
-- t2-- 3)将每行数据中的日期间区Rank值
select id,dt,lowcarbon,date_sub(dt, rk) flag
from t2;
-- t3-- 4) 按照用户及 Flag 分组,求每个组有多少条数据,并找出大于等于3条的数据
select id,flag,count(*) ct
from (select id,dt,lowcarbon,date_sub(dt, rk) flagfrom (select id,dt,lowcarbon,rank() over (partition by id order by dt) rkfrom (select id, dt, sum(lowcarbon) lowcarbonfrom mayigroup by id, dthaving lowcarbon > 100) t1) t2) t3
group by id, flag
having ct >= 3;

2.分组问题

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

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

create table elec
(id int,ts bigint
)row format delimitedfields terminated by '\t';load data local inpath "/home/hadoop/test/elec.txt" into table elec;select *
from elec;
-- 1)将上一行时间数据下移
-- lead:领导
-- lag:延迟
select id,ts,lag(ts, 1, 0) over (partition by id order by ts) lagts
from elec;
-- t1-- 2)将当前行时间数据减去上一行时间数据
select id,ts,ts - lagts tsdiff
from t1;
-- t2
select id,ts,ts - lagts tsdiff
from (select id,ts,lag(ts, 1, 0) over (partition by id order by ts) lagtsfrom elec) t1;-- 3)计算每个用户范围内从第一行到当前行tsdiff大于等于60的总个数(分组号)
select id,ts,sum(if(tsdiff >= 60, 1, 0)) over (partition by id order by ts) groupid
from (select id,ts,ts - lagts tsdifffrom (select id,ts,lag(ts, 1, 0) over (partition by id order by ts) lagtsfrom elec) t1) t2;

3.间隔连续问题

某游戏公司记录的用户每日登录数据
注意:有的时候hql过于复杂,需要spark任务也比较多,可能需要建立临时表分多步运行

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 天登录。

create table user_login
(id int,dt string
)row format delimitedfields terminated by '\t';load data local inpath "/home/hadoop/test/user_login.txt" into table user_login;select *
from user_login;
-- 思路二:分组
-- 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-19
select id,dt,lag(dt, 1, '1970-01-01') over (partition by id order by dt) lagdt
from user_login;
-- t1-- 2)将当前行时间减去上一行时间数据(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  1
select id,dt,datediff(dt, lagdt) flag
from t1;
create table user_login_tmp as
select id,dt,datediff(dt, lagdt) flag
from (select id,dt,lag(dt, 1, '1970-01-01') over (partition by id order by dt) lagdt
from user_login)t1;
select * from user_login_tmp;
-- t2-- 3)按照用户分组,同时按照时间排序,计算从第一行到当前行大于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  2
select id,dt,sum(if(flag > 2, 1, 0)) over (partition by id order by dt) flag
from t2;select id,dt,sum(if(flag > 2, 1, 0)) over (partition by id order by dt) flag2
from (select id,dt,datediff(dt, lagdt) flag
from (select id,dt,lag(dt, 1, '1970-01-01') over (partition by id order by dt) lagdt
from user_login)t1)t2;select id,dt,sum(if(flag > 2, 1, 0)) over (partition by id order by dt) flag2
from user_login_tmp;
-- t3-- 4)按照用户和flag分组,求最大时间减去最小时间并加上1
select id,flag,datediff(max(dt), min(dt)) days
from t3
group by id, flag;
-- t4-- 5)取连续登录天数的最大值
select id,max(days) + 1
from t4
group by id;-- 6)最终HQL
-- 6)最终HQL
-- set yarn.scheduler.maximum-allocation-mb=4;
-- set spark.executor.cores=4;
-- set  spark.executor.instances=6;
-- set  spark.executor.memory="3.2g";
-- set  spark.yarn.executor.memoryOverhead="0.8G";
-- set spark.executor.cores=1;
-- set  spark.executor.instances=24;
-- set  spark.default.parallelism=20;
-- set  spark.driver.memory="819MB";
-- set  spark.driver.memoryOverhead="205MB";set spark.executor.instances = 20;
set  spark.executor.cores = 1;
set spark.executor.memory = 1g;
select id,max(days) + 1
from (select id,flag,datediff(max(dt), min(dt)) daysfrom (select id,dt,sum(if(flag > 2, 1, 0)) over (partition by id order by dt) flagfrom (select id,dt,datediff(dt, lagdt) flagfrom (select id,dt,lag(dt, 1, '1970-01-01') over (partition by id order by dt) lagdtfrom user_login) t1) t2) t3group by id, flag) t4
group by id;
-- join配置
-- set hive.auto.convert.join=false;
--
-- set mapred.map.tasks.speculative.execution=true;
-- set mapred.reduce.tasks.speculative.execution=true;

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

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 天。

drop table if exists  discount;
create table discount
(id string,stt string,edt string
)row format delimitedfields terminated by '\t';load data local inpath "/home/hadoop/test/discount.txt" into table discount;select *
from discount;
-- id        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-- select * from business;
-- select name,orderdate,cost,
-- sum(cost) over() as sample1
--        ,--所有行相加
-- sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4
-- ,--和 sample3 一样,由起点到当前行的聚合
-- sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6
-- --        ,--当前行和前边一行及后面一行
-- from business-- 1)将当前行以前的数据中最大的edt放置当前行selectid,stt,edt,max(edt) over(partition by id order by stt rows between UNBOUNDED PRECEDING and 1 PRECEDING) maxEdt
from discount;
-- 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-- 2)比较开始时间与移动下来的数据,如果开始时间大,则不需要操作,
-- 反之则需要将移动下来的数据 加一 替换当前行的开始时间
-- 如果是第一行数据,maxEDT为null,则不需要操作
selectid,if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt,edt
from t1;
-- t2
-- redmi    2021-06-05  2021-06-21
-- redmi    2021-06-22  2021-06-15
-- redmi    2021-06-22  2021-06-26-- 3)将每行数据中的结束日期减去开始日期
selectid,datediff(edt,stt) days
fromt2;
-- t3
-- redmi    16
-- redmi    -7
-- redmi    4-- 4)按照品牌分组,计算每条数据加一的总和
selectid,sum(if(days>=0,days+1,0)) days
fromt3
group by id;
-- redmi    22-- 5)最终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 discount)t1)t2)t3
group by id;

5.同时在线问题

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

id stt edt
1003 2021-06-14 12:12:12 2021-06-14 18:12:12
1004 2021-06-14 13:12:12 2021-06-14 16: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

drop table if exists  living;
create table living
(id string,stt string,edt string
)row format delimitedfields terminated by '\t';load data local inpath "/home/hadoop/test/living.txt" into table living;select *
from living;
-- 流式!-- 1)对数据分类,在开始数据后添加正1,表示有主播上线,同时在关播数据后添加-1,表示有主播下
select id,stt dt,1 p from living
union
select id,edt dt,-1 p from living;
-- t1
-- 1001 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-- 2)按照时间排序,计算累加人数
selectid,dt,sum(p) over(order by dt) sum_p
from(select id,stt dt,1 p from living
union
select id,edt dt,-1 p from living)t1;
-- t2-- 3)找出同时在线人数最大值
selectmax(sum_p)--  *
from(selectid,dt,sum(p) over(order by dt) sum_p
from(select id,stt dt,1 p from living
union
select id,edt dt,-1 p from living)t1)t2
where dt='2021-06-14 20:12:12';

Hive hql 经典5道面试题相关推荐

  1. ASP.NET 经典60道面试题

    转:http://bbs.chinaunix.net/thread-4065577-1-1.html ASP.NET 经典60道面试题 1. 简述 private. protected. public ...

  2. Java SE 基础部分经典100道笔试题

    这100道题的范围主要是Java SE部分,正在学习Java SE的同学可以做一下,巩固一下学习的知识,也比较适合准备面试的同学复习使用.本题有90道选择题和10道填空题,选择题大部分是单选题,少数为 ...

  3. 数据科学家经典20道面试题

    Q1.解释什么是正则化,以及它为什么有用. 回答者:Matthew Mayo   正则化是添加一个调优参数的过程模型来引导平滑以防止过拟合.(参加KDnuggets文章<过拟合>) 这通常 ...

  4. 嵌入式linux开发考试题目,练一练!3道经典嵌入式Linux面试题,答案在文末。

    原标题:练一练!3道经典嵌入式Linux面试题,答案在文末. 题一: 简述memcpy和strcpy的区别? 题二:信号量与互斥锁的区别? 题三:简述程序编译的过程? 题一答案: (1)复制的内容不同 ...

  5. java接口面试题_7道经典Java接口面试题

    Java接口,Java语言中存在的结构,有特定的语法和结构,是Java面试中经常出现的考点,本文为大家准备了7道经典Java接口面试题. 1.什么是接口 接口就是内部模块对模块,外部系统对其他服务提供 ...

  6. 【转载】经典10道c/c++语言经典笔试题(含全部所有参考答案)

    经典10道c/c++语言经典笔试题(含全部所有参考答案) 1. 下面这段代码的输出是多少(在32位机上). char *p; char *q[20]; char *m[20][20]; int (*n ...

  7. Hive SQL经典面试题:统计连续登陆的三天及以上的用户

    Hive SQL经典面试题 最近发现一道大数据面试经常会问的SQL题目:统计连续登录的三天及以上的用户(或者类似的:连续3个月充值会员用户.连续N天购买商品的用户等),下面就来记录一下解题思路. 要求 ...

  8. 15道非常经典的TCP面试题

    TCP协议是大厂面试必问的知识点.整理了15道非常经典的TCP面试题,希望大家都找到理想的offer呀 以下文章来源于捡田螺的小男孩 ,作者捡田螺的小男孩 讲下TCP三次握手流程 开始客户端和服务器都 ...

  9. 20道经典的AJAX面试题(必知必会)

    1.什么是AJAX,为什么要使用Ajax(请谈一下你对Ajax的认识) 什么是ajax: AJAX是"Asynchronous JavaScript and XML"的缩写.他是指 ...

最新文章

  1. 【Java】LeetCode 876 获取链表中间节点
  2. java免安装工具包_Java1.8安装及环境变量配置
  3. Java矩形区域食物链_AcWing 240. 食物链(JAVA)
  4. 双向循环链表的插入排序
  5. ThinkPHP 模板循环语法
  6. 手把手教你玩转网络编程模型之完成例程(Completion Routine)
  7. ios wkweb设置图片_iOS wkwebview和 uiwebview 内容图片自适应大小
  8. shǎ崽 OrOrOrOrz
  9. python连续写入文件操作_Python实现的读取文件内容并写入其他文件操作示例
  10. PHP-Header缓存策略
  11. 21.docker logs
  12. shell 函数定义及应用
  13. Improving Opencv9 Eroding and Dilating 和对opencv窗体上有控制按钮的理解
  14. 百会云办公:国内首家微信办公一站式解决方案
  15. 计算机软件工程专业大学排名专科,2020软件工程专业大学排名一览表
  16. iOS开发中的零碎知识点笔记 韩俊强的博客
  17. Android安全检测 - Janus签名漏洞
  18. HA集群强制进行Active/Standby切换的命令
  19. 口袋妖怪letsgo服务器几点维护,精灵宝可梦LetsGo每日必做汇总 日常任务推荐
  20. tomcat_修改网页标签图标

热门文章

  1. 请java老鸟指教一下
  2. 面试官问我G1回收器怎么知道你是什么时候的垃圾?
  3. html5怎么调用cur指针,鼠标指针.cur.ani导出与制作
  4. 冈撒雷斯数字图像处理学习笔记
  5. 【MyBatis】基础全网最全,看这篇就够了
  6. CodeChef 遇到 Language Rejected 怎么办
  7. php广告管理,DedeCMS的广告管理功能
  8. 穿过黑暗的夜,才懂黎明的晨
  9. 顺丰丰桥接口开发-java(订单取消接口)
  10. 2020年系统规划与管理师上午真题及答案解析