Hive函数

一、hive语句的执行顺序

1.from

2.join on 或 lateral view explode(扁平化) tbl as 扁平化的列名

3.where

4.group by

5.聚合函数 如Sum() avg() count(1)等

6.having 在此开始可以使用select中的别名

7.select 若包含over()开窗函数,此时select中的内容作为窗口函数的输入,窗口中所选的数据范围也是在group by,having之后,并不是针对where后的数据进行开窗,这点要注意。需要注意开窗函数的执行顺序及时间点。

8.distinct

9.order by

10.limit(建议:今后在大数据环境中,一张表的数据量肯定十分庞大的,养成加limit的习惯)

二、hql中的注意事项

1.where 条件里不支持不等式子查询,hive1.x版本是不支持的,hive3.x版本是支持的

2.hive中大小写不敏感(列名无所谓大小写

3.explain可以查看SQL执行计划(查看更加详细的执行计划,explain后面加上extended)

hive函数官方文档地址:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

三、Hive内置函数

函数用法查看:

-- 1.查看系统自带函数
show functions;
-- 2.显示自带的函数的用法
desc function xxxx;
-- 3.详细显示自带的函数的用法
desc function extended upper;

内置函数分类:

关系操作符:包括 = 、 <> 、 <= 、>=等

算数操作符:包括 + 、 - 、 *、/等

逻辑操作符:包括AND 、 && 、 OR 、 || 等

复杂类型构造函数:包括map、struct、create_union等

复杂类型操作符:包括A[n]、Map[key]、S.x

数学操作符:包括ln(double a)、sqrt(double a)等

集合操作符:包括size(Array)、sort_array(Array)等

类型转换函数: binary(string|binary)、cast(expr as )

日期函数:包括from_unixtime(bigint unixtime[, string format])、unix_timestamp()等

条件函数:包括if(boolean testCondition, T valueTrue, T valueFalseOrNull)等

字符串函数:包括acat(string|binary A, string|binary B…)等

其他:xpath、get_json_objectscii(string str)、con

三种函数种类:

(1)UDF 进一出一

(2)UDAF 进多出一

(3)UDTF 进一出多

-- UDF 进一出一

-- UDAF 进多出一
-- collect_set()和collect_list() 都是对多列转成一行,区别就是list里面可重复而set里面是去重的
-- concat_ws(':',collect_set(列名))   ':' 表示你合并后用什么分隔,collect_set(列名)表示要合并表中的那一列数据
select 字段名,concat_ws(':',collect_set(列名)) as 别名 from 表名 group by id;

-- UDTF 进一出多
-- explode  可以将一组数组的数据变成一列表(扁平化
select  explode(split(列名,"数据的分隔符")) from 表名;
-- lateral view 表生成函数,可以将explode的数据生成一个列表
select id,name,列名 from 表1,lateral view explode(split(表1.列名,"数据的分隔符"))新列名 as 别列名;

1.条件函数

1.1  if

使用场景:数据清洗的过程中使用,有些构建表的过程也是需要的(转换数据信息)

语法:if(表达式,如果表达式成立的返回值,如果表达式不成立的返回值) (类似与java的三目运算符)

举例:

select if(3>1,'yes','no');          --yes

select score,if(score>120,'优秀',if(score>100,'良好',if(score>90,'及格','不及格'))) as pingfen from sc;

1.2  coalesce

从左往右 依次匹配 直到非空为止

select coalesce(null,'1','2');         --1
select coalesce('1',null,'2');         --1

1.3  case when

转换数据信息,与if类似

select  score
        ,case when score>90 then '优秀'
              when score>80 then '良好'
              when score>=60 then '及格'
        else '不及格'
        end as pingfen
from sc;

2.日期函数 

2.1 unix_timestamp()

查询当前时间(时间戳形式)

select unix_timestamp()             -- 1712842504 

2.2  from_unixtime

将时间戳转化为自定义格式

select from_unixtime(1712815703,'YYYY年MM月dd日 HH时mm分ss秒');   

 -- 2024年04月11日 06时08分23秒


// '2021年01月14日' -> '2021-01-14'
select from_unixtime(unix_timestamp('2022年06月06日','yyyy年MM月dd日'),'yyyy-MM-dd');

// "04哥哥2024弟弟11妹妹" -> "2021/04/16"
select from_unixtime(unix_timestamp("04哥哥2024弟弟11妹妹","MM哥哥yyyy弟弟dd妹妹"),"yyyy年MM月dd日");

3.字符串函数

3.1 concat

concat('123','456');                  //123456
select concat('123','null');        //123null
concat('123','456',null);            // NULL

3.2 concat_ws

select concat_ws('#','a','b','c');              //a#b#c
select concat_ws('#','a','b','c',NULL);    //a#b#c 可以指定分隔符,并且会自动忽略NULL
select concat_ws("|",cast(id as string),name,cast(age as string),gender,clazz) from students limit 10;

3.3 substring

select substring("abcdefg",1); // abcdefg HQL中涉及到位置的时候 是从1开始计数

3.4 split

select split("abcde,fgh",",");           //  ["abcde","fgh"]
select split("a,b,c,d,e,f",",")[2];       // c  数组的下标依旧是从0开始

select explode(split("abcde,fgh",",")); // abcde
                                                           //  fgh

3.5 get_json_object

解析json格式的数据

select get_json_object('{"name":"zhangsan","age":18,"score":[{"course_name":"math","score":100},{"course_name":"english","score":60}]}',"$.score[0].score"); // 60

{
    "name": "zhangsan",
    "age": 18,
    "score": [{
        "course_name": "math",
        "score": 100
    }, {
        "course_name": "english",
        "score": 60
    }]
}             

// 60

四、 Hive窗口函数

1.概述:

(1)普通的聚合函数每组(Group by)只返回一个值,而开窗函数则可为窗口中的每行都返回一个值。

(2)简单理解,就是对查询的结果多出一列,这一列可以是聚合值,也可以是排序值。

(3)开窗函数一般就是说的是over()函数,其窗口是由一个 OVER 子句 定义的多行记录

(4)开窗函数一般分为两类,聚合开窗函数和排序开窗函数。

2.语法格式:

-- 聚合格式
select sum(字段名) over([partition by 字段名] [ order by 字段名]) as 别名,
    max(字段名) over() as 别名 
from 表名;

-- 排序窗口格式
select rank() over([partition by 字段名] [ order by 字段名]) as 别名 from 表名;

注意:

  • over()函数中的分区、排序、指定窗口范围可组合使用也可以不指定,根据不同的需求结合使用

  • over()函数中如果不指定分区,窗口大小是针对查询产生的所有数据,如果指定了分区,窗口大小是针对每个分区的数据

3. 聚合开窗函数

sum(求和)

min(最小)

max(最大)

avg(平均值)

count(计数)

lag(获取当前行上一行的数据)

案例:

数据:

-- 创建表
create table t_fraction(
name string,
subject string, 
score int) 
row format delimited fields terminated by ","
lines terminated by '\n';

-- 测试数据 fraction.txt
孙悟空,语文,10
孙悟空,数学,73
孙悟空,英语,15
猪八戒,语文,10
猪八戒,数学,73
猪八戒,英语,11
沙悟净,语文,22
沙悟净,数学,70
沙悟净,英语,31
唐玄奘,语文,21
唐玄奘,数学,81
唐玄奘,英语,23

-- 上传数据
load data local inpath 'linux路径/fraction.txt' into table t_fraction;

数据查询:

select name,subject,score,
sum(score) over() as sum1,
sum(score) over(partition by subject) as sum2,
sum(score) over(partition by subject order by score) as sum3, 

-- 由起点到当前行的窗口聚合,和sum3一样
sum(score) over(partition by subject order by score rows between unbounded preceding and current row) as sum4, 

-- 当前行和前面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 preceding and current row) as sum5,

-- 当前行的前面一行到后面一行的窗口聚合  前一行+当前行+后一行
sum(score) over(partition by subject order by score rows between 1 preceding and 1 following) as sum6,

-- 当前行与后一行之和
sum(score) over(partition by subject order by score rows between current row and 1 following) as sum6,

-- 当前和后面所有的行
sum(score) over(partition by subject order by score rows between current row and unbounded following) as sum7
from t_fraction;

小总结:

rows:行
unbounded preceding:起点
unbounded following:终点
n preceding:前 n 行
n following:后 n 行
current row:当前行

查询结果表:

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

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

CURRENT ROW:当前行

n PRECEDING:往前n行数据

n FOLLOWING:往后n行数据

UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点

LAG(col,n,default_val):往前第n行数据,col是列名,n是往上的行数,当第n行为null的时候取default_val

LEAD(col,n, default_val):往后第n行数据,col是列名,n是往下的行数,当第n行为null的时候取default_val

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

cume_dist(),计算某个窗口或分区中某个值的累积分布。假定升序排序,则使用以下公式确定累积分布:

小于等于当前值x的行数 / 窗口或partition分区内的总行数。其中,x 等于 order by 子句中指定的列的当前行中的值。

4.排序开窗函数

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

  • DENSE_RANK()        排序相同时序号会重复,总数会减少

  • ROW_NUMBER()      排序相同时序号不会重复

  • PERCENT_RANK()    计算给定行的百分比排名。可以用来计算超过了百分之多少的人(当前行的rank值-1)/(分组内的总行数-1)

举例:

select name,subject,score,
rank() over(partition by subject order by score desc) rp,
dense_rank() over(partition by subject order by score desc) drp,
row_number() over(partition by subject order by score desc) rnp,
percent_rank() over(partition by subject order by score) as percent_rank 
from t_fraction;

查询结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值