赞
踩
Hive 是一个建立在 Hadoop 上的数据仓库基础架构,它提供了类似于 SQL 的查询语言,称为 HiveQL,用于对存储在 Hadoop 分布式文件系统中的数据进行查询和分析。
Hive会将常用的逻辑封装成函数给用户进行使用,类似于Java中的方法。
Hive提供了大量的内置函数,按照其特点可大致分为如下几类:单行函数、聚合函数、炸裂函数、窗口函数。
以下命令可用于查询所有内置函数的相关信息。
1)查看系统内置函数
hive> show functions;
2)查看内置函数用法
hive> desc function upper;
3)查看内置函数详细信息
hive> desc function extended upper;
查询出所有员工的薪水后加1显示:
hive (default)> select sal + 1 from emp;
数值函数是用于对数值数据进行操作和计算的函数,在 SQL 查询中经常用于执行数学运算、取值范围限制等操作。
ABS(x):返回 x 的绝对值。
ROUND(x, d):将 x 四舍五入到 d 位小数。如果 d 被省略,则默认为 0。
hive> select round(3.3); 3
hive> select ceil(3.1) ; 4
hive> select floor(4.8); 4
SQRT(x):返回 x 的平方根。
POWER(x, y):返回 x 的 y 次幂。
EXP(x):返回 e 的 x 次幂,其中 e 是自然对数的底。
LOG(x):返回 x 的自然对数。
LOG10(x):返回 x 的以 10 为底的对数。
MOD(x, y):返回 x 除以 y 的余数。
SIGN(x):返回 x 的符号:1 表示正数,-1 表示负数,0 表示零。
RAND():返回一个随机浮点数值,范围在 0 到 1 之间。
示例:
-- 返回 -5 的绝对值
SELECT ABS(-5); -- 输出: 5
-- 将 4.8 四舍五入到最近的整数
SELECT ROUND(4.8); -- 输出: 5
-- 返回不小于 4.8 的最小整数
SELECT CEIL(4.8); -- 输出: 5
-- 返回不大于 4.8 的最大整数
SELECT FLOOR(4.8); -- 输出: 4
-- 返回 25 的平方根
SELECT SQRT(25); -- 输出: 5
-- 返回 2 的 3 次幂
SELECT POWER(2, 3); -- 输出: 8
-- 返回 e 的 2 次幂
SELECT EXP(2); -- 输出: 约为 7.389
-- 返回 100 的自然对数
SELECT LOG(100); -- 输出: 约为 4.605
-- 返回 100 的以 10 为底的对数
SELECT LOG10(100); -- 输出: 2
-- 返回 10 除以 3 的余数
SELECT MOD(10, 3); -- 输出: 1
-- 返回 -5 的符号:-1 表示负数
SELECT SIGN(-5); -- 输出: -1
-- 返回一个范围在 0 到 1 之间的随机浮点数
SELECT RAND(); -- 输出: 0.xxxx (实际结果会变化)
concat
(str1, str2, …):连接字符串。-- 连接 'hello' 和 'world'
SELECT concat('hello', ' ', 'world'); -- 输出: 'hello world'
语法:concat(string A, string B, string C, ……)
返回:string
说明:将A,B,C……等字符拼接为一个字符串
hive> select concat('beijing','-','shanghai','-','shenzhen');
输出:
hive> beijing-shanghai-shenzhen
upper
(str):将字符串转换为大写。
-- 将 'hello' 转换为大写
SELECT upper('hello'); -- 输出: 'HELLO'
lower
(str):将字符串转换为小写。
-- 将 'WORLD' 转换为小写
SELECT lower('WORLD'); -- 输出: 'world'
length
(str):返回字符串的长度。
-- 返回字符串 'hello world' 的长度
SELECT length('hello world'); -- 输出: 11
substr
(str, start, length):提取子串。
-- 提取字符串 'hello world' 的前 5 个字符
SELECT substr('hello world', 1, 5); -- 输出: 'hello'
获取倒数第三个字符以后的所有字符
select substring("yushifu",-3); ifu
replace
(str, from_str, to_str):替换字符串中的子串。
-- 将字符串 'hello world' 中的 'hello' 替换为 'hi'
SELECT replace('hello world', 'hello', 'hi'); -- 输出: 'hi world'
trim
([BOTH | LEADING | TRAILING] trim_str FROM str):去除字符串两侧或指定位置的空格或指定字符。
-- 去除字符串 ' hello world ' 两侧的空格
SELECT trim(' hello world '); -- 输出: 'hello world'
-- 去除字符串 'xxxhello worldxxx' 两侧的 'x'
SELECT trim('x' FROM 'xxxhello worldxxx'); -- 输出: 'hello world'
ltrim
(str):去除字符串左侧的空格。
-- 去除字符串 ' hello' 左侧的空格
SELECT ltrim(' hello'); -- 输出: 'hello'
rtrim
(str):去除字符串右侧的空格。
-- 去除字符串 'world ' 右侧的空格
SELECT rtrim('world '); -- 输出: 'world'
regexp_replace
函数用于使用正则表达式替换字符串中的匹配项。
-- 使用正则表达式替换字符串中的数字为 'X'
SELECT regexp_replace('Hello 123 World 456', '\\d+', 'X');
-- 输出: 'Hello X World X'
'\\d+'
是一个正则表达式,用于匹配一个或多个数字。'X'
是替换字符串。所以,regexp_replace
函数将字符串中的所有数字替换为 'X'
。
11.repeat
:重复字符串
hive> select repeat('123', 3);
输出:
hive> 123123123
12.split
:字符串切割
hive> select split('a-b-c-d','-');
输出:
hive> ["a","b","c","d"]
13.nvl
:替换null值
语法:nvl(A,B)
说明:若A的值不为null,则返回A,否则返回B。
hive> select nvl(null,1);
输出:
hive> 1
14.concat_ws
:以指定分隔符拼接字符串或者字符串数组
hive>select concat_ws('-','beijing','shanghai','shenzhen');
输出:
hive> beijing-shanghai-shenzhen
hive> select concat_ws('-',array('beijing','shenzhen','shanghai'));
输出:
hive> beijing-shanghai-shenzhen
15.get_json_object
:解析json字符串
(1)获取json数组里面的json具体数据
hive> select get_json_object('[{"name":"yushifu","sex":"男","age":"24"},{"name":"彭于晏","sex":"男","age":"47"}]','$.[0].name');
输出:
hive> yushifu
(2)获取json数组里面的数据
hive> select get_json_object('[{"name":"yushifu","sex":"男","age":"24"},{"name":"彭于晏","sex":"男","age":"47"}]','$.[0].name');
输出:
hive> {"name":"yushifu","sex":"男","age":"24"}
1.unix_timestamp
:返回当前或指定时间的时间戳
hive> select unix_timestamp('2024/04/25 09-19-08','yyyy/MM/dd HH-mm-ss');
输出:
1714036748
说明:前面是日期后面是指日期传进来的具体格式
2.from_unixtime
:转化UNIX时间戳(从 1970-01-01 00:00:00 UTC 到指定时间的秒数)到当前时区的时间格式
hive> select from_unixtime(1714036748);
输出:
2024-04-25 09:19:08
3.current_date
:当前日期
hive> select current_date;
输出:
2024-04-25
4.current_timestamp
:当前的日期加时间,并且精确的毫秒
hive> select current_timestamp;
输出:
2024-04-25 09:22:22.726
5.month
:获取日期中的月
hive> select month('2024-04-25 09:19:08');
输出:
4
6.day
:获取日期中的日
hive> select day('2024-04-25 09:19:08');
输出:
25
7.hour
:获取日期中的小时
hive> select hour('2024-04-25 09:19:08');
输出:
9
8)datediff
:两个日期相差的天数(结束日期减去开始日期的天数)
hive> select datediff('2021-08-08','2022-10-09');
输出:
-427
9.date_add
:日期加天数
hive> select date_add('2022-08-08',2);
输出:
2022-08-10
10.date_sub
:日期减天数
hive> select date_sub('2022-08-08',2);
输出:
2022-08-06
11.date_format
:将标准日期解析成指定格式字符串
hive> select date_format('2022-08-08','yyyy年-MM月-dd日')
输出:
2022年-08月-08日
1. case when:条件判断函数
hive> select case when 1=2 then 'tom' when 2=2 then 'mary' else 'tim' end ;
mary
hive> select case 100 when 50 then 'tom' when 100 then 'mary' else 'tim' end;
mary
求出不同部门男女各多少人
emp_sex 表:
hive (default)>
select
dept_id,
sum(case sex when '男' then 1 else 0 end) male_count,
sum(case sex when '女' then 1 else 0 end) female_count
from emp_sex
group by dept_id;
2. if: 条件判断,类似于Java中三元运算符
(1)条件满足,输出正确
hive> select if(10 > 5,'正确','错误');
输出:正确
(2)条件满足,输出错误
hive> select if(10 < 5,'正确','错误');
输出:错误
1.size:集合中元素的个数
hive> select size(friends) from test;
--2/2 每一行数据中的friends集合里的个数
2.map:创建map集合
hive> select map('uzi',1,'xiaohu',2);
输出:
hive> {"uzi":1,"xiaohu":2}
3.map_keys: 返回map中的key
hive> select map_keys(map('uzi',1,'xiaohu',2));
输出:
hive>["uzi","xiaohu"]
4.map_values: 返回map中的value
hive> select map_values(map('uzi',1,'xiaohu',2));
输出:
hive>[1,2]
5.array:声明array集合
hive> select array('1','2','3','4');
输出:
hive>["1","2","3","4"]
6.array_contains: 判断array中是否包含某个元素
hive> select array_contains(array('a','b','c','d'),'a');
输出:
hive> true
7.sort_array:将array中的元素排序
hive> select sort_array(array('a','d','c'));
输出:
hive> ["a","c","d"]
8.struct:声明struct中的各属性
语法:struct(val1, val2, val3, …)
说明:根据输入的参数构建结构体struct类
hive> select struct('name','age','weight');
输出:
hive> {"col1":"name","col2":"age","col3":"weight"}
9.named_struct:声明struct的属性和值
hive> select named_struct('name','uzi','age',18,'weight',80);
输出:
hive> {"name":"uzi","age":18,"weight":80}
多进一出 (多行传入,一个行输出)。
count(distinct expr[, expr…]):
select count(distinct user_id) from table;
collect_set(expr):
select collect_set(city) from users group by country;
hive>
select
sex,
collect_set(job)
from
employee
group by
sex
select collect_list(product_name) from sales group by order_id;
每个月的入职人数以及姓名
hive>
select
month(replace(hiredate,'/','-')) as month,
count(*) as cn,
Collect_list(name) as name_list
from
employee
group by
month(replace(hiredate,'/','-'))
month cn name_list
4 2 ["宋青书","周芷若"]
6 1 ["黄蓉"]
7 1 ["郭靖"]
8 2 ["张无忌","杨过"]
9 2 ["赵敏","小龙女"]
grouping sets:
select dept_id, gender, count(*) from employees group by grouping sets (dept_id, gender, ());
rollup:
select dept_id, gender, count(*) from employees group by rollup (dept_id, gender);
cube:
select dept_id, gender, count(*) from employees group by cube (dept_id, gender);
percentile(expr, p):
select percentile(salary, 0.75) from employee_salaries;
ntile(n):
select name, salary, ntile(4) over (order by salary) as quartile from employees;
Hive中的炸裂函数通常用于将包含多个元素的字符串或数组拆分成单独的元素,并生成新的行。
explode():将数组拆分成单独的元素,并为每个元素生成新的行。
SELECT explode(array_column) AS single_element FROM table;
posexplode():类似于explode(),但同时返回元素的位置索引。
SELECT posexplode(array_column) AS (pos, single_element) FROM table;
示例:
+-------------+-------------------+
| student_id | grades |
+-------------+-------------------+
| 1 | ["Math: A", "Science: B", "History: A"] |
| 2 | ["Math: B", "Science: A", "History: C"] |
+-------------+-------------------+
使用explode()
函数将grades
数组拆分为单独的行
SELECT student_id, explode(grades) AS subject_grade
FROM student_grades;
+-------------+-------------------+
| student_id | subject_grade |
+-------------+-------------------+
| 1 | "Math: A" |
| 1 | "Science: B" |
| 1 | "History: A" |
| 2 | "Math: B" |
| 2 | "Science: A" |
| 2 | "History: C" |
+-------------+-------------------+
每个学生的每个科目成绩都变成了一行。
如果还想保留每个成绩的位置索引,可以使用posexplode()
函数:
SELECT student_id, posexplode(grades) AS (pos, subject_grade)
FROM student_grades;
+-------------+------+-------------------+
| student_id | pos | subject_grade |
+-------------+------+-------------------+
| 1 | 0 | "Math: A" |
| 1 | 1 | "Science: B" |
| 1 | 2 | "History: A" |
| 2 | 0 | "Math: B" |
| 2 | 1 | "Science: A" |
| 2 | 2 | "History: C" |
+-------------+------+-------------------+
按照功能,常用窗口可划分为如下几类:聚合函数、跨行取值函数、排名函数。
SUM()
, AVG()
, COUNT()
, MAX()
, MIN()
。LEAD()
, LAG()
, FIRST_VALUE()
, LAST_VALUE()
。lead():该函数用于获取当前行之后偏移量为offset的行的值。
lead(salary, 1, 0) over (order by date) as next_salary
lag():该函数用于获取当前行之前偏移量为offset的行的值。
lag(salary, 1, 0) over (order by date) as prev_salary
first_value():该函数用于获取窗口内第一行的值。
first_value(salary) over (partition by department order by hire_date) as first_salary
last_value():该函数用于获取窗口内最后一行的值。
last_value(salary) over (partition by department order by hire_date rows between unbounded preceding and unbounded following) as last_salary
这些函数可以根据具体需求结合使用,对数据进行各种类型的分析和比较,例如计算变化率、检测趋势、识别异常值等。在处理时间序列数据或需要考虑数据历史变化的情况下,这些函数尤其有用。
ROW_NUMBER()
, RANK()
, DENSE_RANK()
, NTILE()
。这些函数通常用于在 hive 中对查询结果进行排序和分组,并为每行分配一个序号或者分组号。让我详细解释一下它们的用法:
row_number():
row_number() over (order by column1 [, column2, ...])
select column1, column2, row_number() over (order by column1) as row_num
from table_name;
row_number()
函数按照 order by
子句中指定的列进行排序,然后为每一行分配一个连续的唯一序号。rank():
rank() over (order by column1 [, column2, ...])
select column1, column2, rank() over (order by column1) as rank
from table_name;
rank()
函数按照 order by
子句中指定的列进行排序,并为相同值的行分配相同的排名,但是可能会跳过排名(比如有两行值相同,排名为 1 和 2,下一行排名可能是 4)。dense_rank():
dense_rank() over (order by column1 [, column2, ...])
select column1, column2, dense_rank() over (order by column1) as dense_rank
from table_name;
dense_rank()
函数按照 order by
子句中指定的列进行排序,并为相同值的行分配相同的排名,但是不会跳过排名(比如有两行值相同,排名为 1 和 2,下一行排名仍然是 3)。ntile():
ntile(n) over (order by column1 [, column2, ...])
select column1, column2, ntile(4) over (order by column1) as quartile
from table_name;
ntile(n)
函数将查询结果集分成 n
个桶,并为每个桶中的行分配一个桶号(从 1 到 n
)。如果行数不能被 n
整除,最后一个桶中的行数可能会少于其他桶。标准函数无法满足需求时,就可以考虑编写自定义函数。这些函数可以用Java编写,并通过Hive的UDF、UDAF、UDTF接口来实现。
标量函数(UDF - User-Defined Function):
org.apache.hadoop.hive.ql.udf.generic.GenericUDF
类,并实现evaluate()
方法来定义函数的逻辑。然后编译成JAR文件,并在Hive中注册该函数。聚合函数(UDAF - User-Defined Aggregate Function):
org.apache.hadoop.hive.ql.exec.UDAFEvaluator
接口,并实现一系列方法来定义聚合函数的行为,包括init()
, iterate()
, terminatePartial()
, merge()
, terminate()
等。然后编译成JAR文件,并在Hive中注册该函数。表生成函数(UDTF - User-Defined Table-Generating Function):
org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
类,并实现process()
方法来定义函数的逻辑。然后编译成JAR文件,并在Hive中注册该函数。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。