hive场景题

文章目录

1、了解哪些窗口函数,都是什么功能?找一个在某个业务中的应用? 手写窗口函数及功能意义,同时随便写一个带窗口函数的sql,并说明其sql的含义。
窗口函数 over() 又名开窗函数,属于分析函数的一种。

sum(col) over() : 分组对col累计求和
count(col) over() : 分组对col累计
min(col) over() : 分组对col求最小
max(col) over() : 分组求col的最大值
avg(col) over() : 分组求col列的平均值
first_value(col) over() : 某分区排序后的第一个col值
last_value(col) over() : 某分区排序后的最后一个col值
lag(col,n,DEFAULT) : 统计往前n行的col值,n可选,默认为1DEFAULT当往上第n行为 NULL 时候, 取默认值,如不指定,则为 NULL
lead(col,n,DEFAULT) : 统计往后n行的col值,n可选,默认为1DEFAULT当往下第n行为 NULL 时候, 取默认值,如不指定,则为 NULL
ntile(n) : 用于将分组数据按照顺序切分成n片,返回当前切片值。注意:n必须为int类型。

排名函数:
row_number() over() : 排名函数,不会重复,适合于生成主键或者不并列排名
rank() over() : 排名函数,有并列名次,名次不连续。如:1,1,3 
dense_rank() over() : 排名函数,有并列名次,名次连续。如:112

over() 函数的用法
distribute by + sort by 组合
位置:在over函数的小阔号
写法:可以单独使用,也可以一起组合使用
    如:
    over(distribute by colName)
    over(sort by colName)
    over(distribute by colName sort by colName [asc|desc])
作用:
   distribute by colName:用于指定分组字段,表示按照指定字段分组,那么每一组对应一个窗口,如果没有,则表示整张表为一组
   sort by colName: 用于排序,如果没有distribute by组合,表示整张表为一组,进行排序,如果有则组内进行排序

partition by +order by 组合
位置:还是在over小括号里
写法:可以单独使用,也可以一起组合使用
	如:
    over(partition by colName)
    over(order by colName)
    over(partition by colName order by colName [asc|desc])
作用:与 distribute by + sort by 组合效果一模一样。  

over(分组 排序 窗口)中的 order by 后使用 window 子句
作用:window子句用来更细粒度的管理窗口大小的

current row: 当前行
preceding:  向前
following:  向后
unbounded preceding: 从起点
unbounded following: 到终点

例如:
select name,orderdate,cost,
sum(cost) over() as sample1,--所有行相加
sum(cost) over(partition by name) as sample2,-- 按name分组,组内数据相加
sum(cost) over(partition by name order by orderdate) as sample3,-- 按name分组,组内数据累加
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 current row) as sample5, -- 当前行和前面一行做聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and 1 FOLLOWING  ) as sample6,-- 当前行和前边一行及后面一行
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 -- 当前行及后面所有行     
from t_order;
2、求出每个栏目的被观看次数及累计观看时长?

数据: video表

uid channel min 
1 1 23
2 1 12
3 1 12
4 1 32
5 1 342
6 2 13
7 2 34
8 2 13
9 2 134
drop table video;
create table video( 
uid int, 
channel string, 
min int 
)
row format delimited 
fields terminated by ' ' 
;
load data local inpath './hivedata/video.txt' into table video;

答案:

select channel,sum(min) from video group by channel;
3、编写sql实现

数据:

userid,month,visits 
A,2015-01,5
A,2015-01,15
B,2015-01,5
A,2015-01,8
B,2015-01,25
A,2015-01,5
A,2015-02,4
A,2015-02,6
B,2015-02,10
B,2015-02,5
A,2015-03,16
A,2015-03,22
B,2015-03,23
B,2015-03,10
B,2015-03,1
drop table visits;
create table visits(
userid string, 
month string, 
visits int 
)
row format delimited 
fields terminated by ',' 
;
load data local inpath './hivedata/visits.txt' overwrite into table visits; 

完成需求:每个用户截止到每月为止的最大单月访问次数和累计到该月的总访问次数,结果数据格式如下:

+---------+----------+---------+-------------+---------------+--+
| userid  |  month   | visits  | max_visits  | total_visits  |
+---------+----------+---------+-------------+---------------+--+
| A       | 2015-01  | 33      | 33          | 33            |
| A       | 2015-02  | 10      | 33          | 43            |
| A       | 2015-03  | 38      | 38          | 81            |
| B       | 2015-01  | 30      | 30          | 30            |
| B       | 2015-02  | 15      | 30          | 45            |
| B       | 2015-03  | 34      | 34          | 79            |
+---------+----------+---------+-------------+---------------+--+
select t.userid,t.month,t.visits,
max(t.visits) over(distribute by t.userid sort by t.month asc) as max_visits,
sum(t.visits) over(distribute by t.userid sort by t.month asc) as total_visits 
from 
(select userid,month,sum(visits) as visits from visits group by userid,month) t;
4、编写连续7天登录的总人数:

数据: t1表

Uid dt login_status(1登录成功,0异常) 
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 
2 2019-07-19 1 
2 2019-07-20 0 
2 2019-07-21 1 
2 2019-07-22 0 
2 2019-07-23 1 
2 2019-07-24 0 
3 2019-07-11 1 
3 2019-07-12 1 
3 2019-07-13 1 
3 2019-07-14 1 
3 2019-07-15 1 
3 2019-07-16 1 
3 2019-07-17 1 
3 2019-07-18 1 
drop table login;
create table login( 
Uid int, 
dt string, 
login_status int 
)
row format delimited 
fields terminated by ' ' 
;

load data local inpath './hivedata/login.txt' into table login; 
-- 1) 用窗口函数,根据uid分组,日期排序
select uid,dt,row_number() over(distribute by uid sort by dt) from login where login_status=1;

-- 2) 在第一步基础上使用 date_sub日期函数计算出每个日期排名前的日期
select t1.uid,date_sub(t1.dt,t1.num) dt from
(select uid,dt,row_number() over(distribute by uid sort by dt) num
from login where login_status=1) t1;

-- 3) 在第二步的基础上,根据用户id和日期分组,计算日期数目大于7的用户
select uid,dt from
(select t1.uid,date_sub(t1.dt,t1.num) dt from
(select uid,dt,row_number() over(distribute by uid sort by dt) num
from login where login_status=1) t1) t2
group by uid,dt
having count(uid)>7;
5、你知道的排名函数有哪些?说一说它们之间的区别? 文字说明即可
1. row_number()  分数有相同,名次是连续不重复的
    分数   名次
    100     1
    99      2
    99      3
    98      4
    
2. rank()         分数相同,名次有重复,是间断的
    分数   名次
    100     1
    99      2
    99      2
    98      4
    
3. dense_rank()    分数有相同,名次重复不间断
    分数   名次
    100     1
    99      2
    99      2
    98      3
    
这三个排名函数,不能单独使用,也必须配合over函数一起使用。
6、编写sql语句实现每班前三名,分数一样不并列,同时求出前三名按名次排序的一次的分差:

数据: stu表

Stu_no class score 
1	1901	90
2	1901	90
3	1901	83
4	1901	60
5	1902	66
6	1902	23
7	1902	99
8	1902	67
9	1902	87
drop table stu;
create table stu( 
Stu_no int, 
class string, 
score int 
)
row format delimited 
fields terminated by '\t' 
;

load data local inpath './hivedata/stu.txt' into table stu; 

编写sql实现,结果如下:

+--------+---------+--------+-----+----------+--+
| class  | stu_no  | score  | rn  | rn_diff  |
+--------+---------+--------+-----+----------+--+
| 1901   | 2       | 90     | 1   | 90       |
| 1901   | 1       | 90     | 2   | 0        |
| 1901   | 3       | 83     | 3   | -7       |
| 1902   | 7       | 99     | 1   | 99       |
| 1902   | 9       | 87     | 2   | -12      |
| 1902   | 8       | 67     | 3   | -20      |
+--------+---------+--------+-----+----------+--+
-- 1) 先查score排序排名后的表
select class,stu_no,score,row_number() over(distribute by class sort by score desc) rn from stu;

-- 2) 基于 1 查出的虚拟表用 where 条件查出前3名 
select * from
(select class,stu_no,score,row_number() over(distribute by class sort by score desc) rn from stu) t where t.rn<=3-- 3)使用lag查找前一行记录
-- lag(列名,n,m):  当前记录前面第n行记录的<列名>的值,没有则默认值为m;如果不带参数n,m,则查找当前记录前面第一行的记录<列名>的值,没有则默认值为null
select t.*,t.score-nvl(lag(score) over(distribute by class sort by rn),0) rn_diff from
(select class,stu_no,score,row_number() over(distribute by class sort by score desc) rn 
from stu) t where t.rn<=3;
7、对于行列互换,你有哪些解决方式,详细说明每一种方式? 使用语言描述即可
行转列: 
1、使用 case when 查询出多列即可,即可增加列。 


列转行: 
1、lateral view explode(),使用展开函数可以将1列转成多行,被转换列适用于array、map等类型。 

posexplode 相比在 explode 之上,将一列数据转为多行之后,还会输出数据的下标。

lateral view posexplode(数组),如有排序需求,则需要索引。将数组展开成两行(索引 
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.上传tar包 2.解压 tar -zxvf hive-1.2.1.tar.gz 3.安装mysql数据库 推荐yum 在线安装 4.配置hive (a)配置HIVE_HOME环境变量 vi conf/hive-env.sh 配置其中的$hadoop_home (b)配置元数据库信息 vi hive-site.xml 添加如下内容: javax.jdo.option.ConnectionURL jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true JDBC connect string for a JDBC metastore javax.jdo.option.ConnectionDriverName com.mysql.jdbc.Driver Driver class name for a JDBC metastore javax.jdo.option.ConnectionUserName root username to use against metastore database javax.jdo.option.ConnectionPassword hadoop password to use against metastore database 5.安装hive和mysq完成后,将mysql的连接jar包拷贝到$HIVE_HOME/lib目录下 如果出现没有权限的问,在mysql授权(在安装mysql的机器上执行) mysql -uroot -p #(执行下面的语句 *.*:所有库下的所有表 %:任何IP地址或主机都可以连接) GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES; 6. Jline包版本不一致的问,需要拷贝hive的lib目录中jline.2.12.jar的jar包替换掉hadoop中的 /home/hadoop/app/hadoop-2.6.4/share/hadoop/yarn/lib/jline-0.9.94.jar 启动hive bin/hive ---------------------------------------------------------------------------------------------------- Hive几种使用方式: 1.Hive交互shell bin/hive 2.Hive JDBC服务(参考java jdbc连接mysql) 3.hive启动为一个服务器,来对外供服务 bin/hiveserver2 nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err & 启动成功后,可以在别的节点上用beeline去连接 bin/beeline -u jdbc:hive2://mini1:10000 -n root 或者 bin/beeline ! connect jdbc:hive2://mini1:10000 4.Hive命令 hive -e ‘sql’ bin/hive -e 'select * from t_test'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值