hive的DDL和DML操作(四)

一、窗口函数(开窗函数)

1. 函数说明

OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。

CURRENT ROW:当前行

n PRECEDING:往前 n 行数据 n FOLLOWING:往后 n 行数据

UNBOUNDED:起点,

UNBOUNDED PRECEDING 表示从前面的起点,

UNBOUNDED FOLLOWING 表示到后面的终点
LAG(col,n,default_val):往前第 n 行数据
LEAD(col,n, default_val):往后第 n 行数据

NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对 于每一行,NTILE 返回此行所属的组的编号。注意:n 必须为 int 类型。

2.案例说明

(1)数据准备
jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94
(2)创建表并加载数据

create table business(name string,orderdate string,cost int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

load data local inpath '/opt/moudle/hive/data/business.txt' into table business;

(3)按需求查询数据

1)查询在 2017 年 4 月份购买过的顾客及总人数

substring(str, pos[,len]) 函数说明:

select substring(orderdate,0,2) from business;#取orderdate的前两个字

在这里插入图片描述

select name,count(*) over() 
from business 
where substring(orderdate,0,7)='2017-04' 
group by name;
select name,count(*) over() from business group by name;
select name,count(*) from business group by name;
#有over()的情况下,是统计一共有多少个不同的name,name字段中一共有4个
#不同的人名,因此返回的值是4
#没有over()的情况下,是统计每个name出现的次数

2)查询顾客的购买明细及顾客月购买总额

#查询顾客的购买明细及购买总额
select name,orderdate,cost,sum(cost) 
over(partition by name) # partition by 只能在over中使用
from business; #partition by 相当于对name进行了分组,先分组在统计

#查询顾客的购买明细及顾客月购买总额
select name,orderdate,cost,sum(cost) 
over(partition by name,month(orderdate)) #按名字和月份进行统计
from business;

在这里插入图片描述
3)将每个顾客的 cost 按照日期进行累加

select name,orderdate,cost,sum(cost)
over(partition by name order by orderdate)#按name分组
#order by 对窗口内进行排序,并对每个日期进行累加
from business;
#还可以写成:
select name,orderdate,cost,sum(cost)
over(partition by name order by orderdate 
rows between unbounded preceding and current row)
from business;
#如果over内没有添加窗口指令,默认是从开始到当前行。

在这里插入图片描述
前一行cost和当前行的cost以及后一行的cost相加

select name,orderdate,cost,sum(cost)
over(partition by name order by orderdate 
rows between 1 PRECEDING and 1 FOLLOWING)
from business;
#第一行cost=10,前一行没有数据,后一行数据为46,则两个相加就是得到的结果
#第二行cost=46,前一行cost=10,后一行cost=55,则三个数相加就是最后结果

在这里插入图片描述

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 business;

rows 必须跟在 order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分 区中的数据行数量

4)查看顾客上次的购买时间
LAG(col,n,default_val):往前第 n 行数据
default_val:默认值,如果是空值,将填充该数据

select name,orderdate,lag(orderdate,1)
over(partition by name order by orderdate)
from business;

在这里插入图片描述

select name,orderdate,lag(orderdate,1,orderdate)
over(partition by name order by orderdate)
from business;

在这里插入图片描述
LEAD(col,n, default_val):往后第 n 行数据

select name,orderdate,lead(orderdate,1,orderdate)
over(partition by name order by orderdate)
from business;

在这里插入图片描述

5)查询前 20%时间的订单信息

NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对于每一行,NTILE 返回此行所属的组的编号。

select * from (
select name,orderdate,cost, 
ntile(5) over(order by orderdate) groupId 
from business
) t1
where groupId = 1;

在这里插入图片描述

3.RANK函数

(1)函数说明

RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算

(2)案例说明

1)数据准备

孙悟空 语文 87
孙悟空 数学 95
孙悟空 英语 68
大海 语文 94
大海 数学 56
大海 英语 84
宋宋 语文 64
宋宋 数学 86
宋宋 英语 84
婷婷 语文 65
婷婷 数学 85
婷婷 英语 78
2)创建表并导入数据

create table score( name string, subject string, score int)
row format delimited fields terminated by "\t";

load data local inpath '/opt/moudle/hive/data/score.txt' into table score;

3)计算每门学科成绩排名

RANK() 排序相同时会重复,总数不会变

select name,
subject, score,
rank() over(partition by subject order by score desc) rp
from score;

在这里插入图片描述
DENSE_RANK() 排序相同时会重复,总数会减少

select name,
subject, score,
dense_rank() over(partition by subject order by score desc) drp
from score;

在这里插入图片描述
ROW_NUMBER() 会根据顺序计算

select name,
subject, score,
row_number() over(partition by subject order by score desc) rmp
from score;

在这里插入图片描述
4)求出每门学科前三名的学生

select name,subject,score
from(select *, 
rank() over(partition by subject order by score desc) rk
from score) t1
where rk<=3;

在这里插入图片描述

4.其他常用函数

日期函数

(1)获取当前时间current_timestamp()

select current_timestamp();

(2)获取当前时间戳unix_timestamp()

select unix_timestamp()

(3)时间戳转回日期格式from_unixtime()

select from_unixtime(1634560912);

(4)获取当前日期current_date()

select current_date();

(5)获取中间日期

select to_date('2021-10-18 20:48:21');

(6)获取年、月、日、时、分、秒

select year('2021-10-18 20:48:21');
select month('2021-10-18 20:48:21');
select day('2021-10-18 20:48:21');
select hour('2021-10-18 20:48:21');
select minute('2021-10-18 20:48:21');
select second('2021-10-18 20:48:21');

(7)两个日期之间的月份 months_between

select months_between('2021-08-21','2021-03-21');

(8)日期加减月add_months

select add_months('2021-02-22',3);

(9)计算两个日期相差的天数datediff

select datediff('2021-10-1','2021-10-8');

(10)日期加天数date_add

select date_add('2021-10-01',3);

(11)日期减天数date_sub

select date_sub('2021-10-01',3);

(12)日期当月的最后一天last_day

select last_day('2021-10-2');

(13)日期格式化

select date_format('2021-10-2','yyyy/mm/dd');

常用取整函数
(1)round四舍五入

select round(3.14159);

在这里插入图片描述

(2)ceil向上取整

select ceil(3.14);

在这里插入图片描述

(3)floor向下取整

select floor(3.14);

在这里插入图片描述
常用字符串操作函数
(1)upper转大写

select upper("abc");

(2)lower转小写

select upper("ABC");

(3)length长度

select length("abc");

(4)trim前后去空格

select trim("   abc  ");

(5)lpad向左补齐,到指定长度

select lpad('de',5,'abc');

在这里插入图片描述

(6)rpad向右补齐,到指定长度

select rpad('ab',5,'cde');

在这里插入图片描述

(7)regexp_replace使用正则表达式匹配目标字符串,匹配成功后替换

select regexp_replace('2021/10/19','/','-');

在这里插入图片描述
集合函数
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing

create table map_test( 
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
row format delimited fields terminated by ',' 
collection items terminated by '_'
map keys terminated by ':' lines terminated by '\n';

(1)size 集合中元素的个数

select size(friends) from map_test;

在这里插入图片描述

(2)map_keys 返回map中的key

select map_keys(children) from map_test;

在这里插入图片描述

(3)map_values 返回map中的values

select map_values(children) from map_test;

在这里插入图片描述

(4)array_contains 判断array中是否包含某个元素

select array_contains(friends,'bingbing') from map_test;

在这里插入图片描述

(5)sort_array 将array中的元素排序

select sort_array(friends) from map_test;

在这里插入图片描述
hive实现wordcount

hello,world
hello,hive,spark,hadoop
hello,zookeeper,spark,flink
hive,spark,hadoop

create table input(words string);

load data local inpath '/opt/moudle/hive/data/input.txt' into table input;

hive实现

select word,count(*) from
(select explode(split(words,',')) word from input) t1
group by word;

在这里插入图片描述

5.自定义函数

根据用户自定义函数类别分为以下三种:
(1)UDF(User-Defined-Function)一进一出
(2)UDAF(User-Defined Aggregation Function)聚集函数,多进一出 类似于:count/max/min
(3)UDTF(User-Defined Table-Generating Functions) 一进多出

可以参考尚硅谷的课程
https://www.bilibili.com/video/BV1EZ4y1G7iL?p=87&spm_id_from=pageDriver

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值