文章目录
- 前言
- 一、Hive内置函数
-
- [1. 数值函数](#1. 数值函数)
- [2. 字符串函数](#2. 字符串函数)
- [3. 日期与时间函数](#3. 日期与时间函数)
- [4. 条件函数](#4. 条件函数)
- [5. 聚合函数](#5. 聚合函数)
- [6. 集合函数](#6. 集合函数)
- [7. 类型转换函数](#7. 类型转换函数)
- [8. 表生成函数 (UDTF)](#8. 表生成函数 (UDTF))
前言
在大数据处理和分析的过程中,数据的转换和处理是至关重要的环节。Apache Hive作为一种流行的数据仓库工具,提供了丰富的内置函数,帮助用户高效地处理和分析存储在Hadoop分布式文件系统(HDFS)中的数据。这些内置函数涵盖了数值计算、字符串处理、日期与时间操作、条件判断、聚合计算、集合处理、类型转换以及用户定义的表生成函数(UDTF)等多个方面。本篇文章将详细介绍Hive中的内置函数,包括它们的功能、用法和示例。通过对这些函数的深入理解,用户可以更灵活地进行数据查询和分析,提升数据处理的效率和准确性。无论是在数据清洗、转换还是复杂查询中,掌握这些内置函数都将为用户提供强大的支持,帮助他们更好地应对大数据环境下的各种挑战。
一、Hive内置函数
1. 数值函数
数值函数用于处理和转换数值数据。以下是一些常用的Hive数值函数及其功能的详细描述:
函数名称 | 描述 | 示例 |
---|---|---|
ABS(x) | 返回x的绝对值。 | SELECT ABS(-2.3); 结果:2.3 |
CEIL(x), CEILING(x) | 返回大于或等于x的最小整数。 | SELECT CEIL(2.1); 结果:3 |
FLOOR(x) | 返回小于或等于x的最大整数。 | SELECT FLOOR(2.9); 结果:2 |
ROUND(x, d) | 将x四舍五入到d位小数,默认d为0。如果d是负数,则对整数部分进行四舍五入。 | SELECT ROUND(2.678, 2); 结果:2.68 |
EXP(x) | 计算e的x次幂(自然指数)。 | SELECT EXP(1); 结果:2.718281828459045 |
LN(x) | 计算x的自然对数。 | SELECT LN(2.718281828459045); 结果:1 |
LOG(x, y) | 计算以x为底y的对数。若仅提供一个参数,则默认以10为底。 | SELECT LOG(2, 8); 结果:3 |
POW(x, p), POWER(x, p) | 计算x的p次幂。 | SELECT POW(2, 3); 结果:8 |
SQRT(x) | 计算x的平方根。 | SELECT SQRT(16); 结果:4 |
SIN(x) | 计算x的正弦值(x为弧度)。 | SELECT SIN(PI()/2); 结果:1 |
COS(x) | 计算x的余弦值(x为弧度)。 | SELECT COS(0); 结果:1 |
TAN(x) | 计算x的正切值(x为弧度)。 | SELECT TAN(PI()/4); 结果:1 |
PI() | 返回π的近似值。 | SELECT PI(); 结果:3.141592653589793 |
RAND([seed]) | 返回0到1之间的随机数。可选参数seed用于生成特定序列的随机数。 | SELECT RAND(); 结果:某个介于0和1之间的随机数 |
SIGN(x) | 如果x是正数返回1,如果是负数返回-1,如果是0则返回0。 | SELECT SIGN(-10); 结果:-1 |
2. 字符串函数
字符串函数用于处理和转换字符串数据。这些函数能够帮助用户执行各种操作,如字符串连接、查找、替换、截取等。以下是一些常用的Hive字符串函数及其功能的详细描述:
函数名称 | 描述 | 示例 |
---|---|---|
CONCAT(string1, string2, ...) | 连接多个字符串。如果任意一个输入参数为null,则整个结果为null。 | SELECT CONCAT('Hello', ' ', 'World'); 结果:Hello World |
CONCAT_WS(separator, string1, string2, ...) | 使用指定的分隔符连接多个字符串。 | SELECT CONCAT_WS('-', 'Hello', 'World'); 结果:Hello-World |
SUBSTRING(string, start, length) 或 SUBSTR(string, start, length) | 从指定位置开始提取指定长度的子串。start从1开始计数。 | SELECT SUBSTRING('Hive', 1, 2); 结果:Hi |
TRIM(BOTH|LEADING|TRAILING chars FROM str) | 移除字符串两端、前缀或后缀的指定字符。默认移除空格。 | SELECT TRIM(BOTH 'x' FROM 'xxxHivexxx'); 结果:Hive |
LTRIM(string), RTRIM(string) | 分别移除字符串左侧或右侧的空格。 | SELECT LTRIM(' Hive '); 结果:Hive |
LOWER(string), LCASE(string) | 将字符串转换为小写。 | SELECT LOWER('HIVE'); 结果:hive |
UPPER(string), UCASE(string) | 将字符串转换为大写。 | SELECT UPPER('hive'); 结果:HIVE |
LENGTH(string) | 返回字符串的长度。 | SELECT LENGTH('Hive'); 结果:4 |
REPEAT(string, n) | 将字符串重复n次。 | SELECT REPEAT('Hive', 3); 结果:HiveHiveHive |
REPLACE(string, search, replace) | 在字符串中搜索并替换所有出现的search为replace。 | SELECT REPLACE('Hello Hive', 'Hive', 'World'); 结果:Hello World |
STRPOS(string, substring) | 查找substring在string中的起始位置。返回0表示未找到。 | SELECT STRPOS('Hello Hive', 'Hive'); 结果:7 |
INITCAP(string) | 将每个单词的第一个字母转为大写,其余字母转为小写。 | SELECT INITCAP('hello hive'); 结果:Hello Hive |
REGEXP_REPLACE(string, pattern, replacement) | 使用正则表达式匹配并替换字符串。 | SELECT REGEXP_REPLACE('Hello Hive', 'H.*e$', 'Hi'); 结果:Hi |
REGEXP_EXTRACT(string, pattern, group) | 使用正则表达式提取匹配的部分。group指定捕获组索引。 | SELECT REGEXP_EXTRACT('Hello Hive', 'H(.*)e', 1); 结果:llo Hiv |
3. 日期与时间函数
日期与时间函数用于处理和转换日期及时间数据。这些函数能够帮助用户执行各种操作,如获取当前日期、计算日期差异、添加或减去日期等。以下是一些常用的Hive日期与时间函数及其功能的详细描述:
函数名称 | 描述 | 示例 |
---|---|---|
CURRENT_DATE | 返回当前日期。 | SELECT CURRENT_DATE; 结果:当前日期(格式:YYYY-MM-DD ) |
CURRENT_TIMESTAMP | 返回当前日期和时间。 | SELECT CURRENT_TIMESTAMP; 结果:当前时间戳 |
DATE_ADD(date, days) | 在给定日期上加上指定天数。 | SELECT DATE_ADD('2025-02-09', 1); 结果:2025-02-10 |
DATE_SUB(date, days) | 从给定日期减去指定天数。 | SELECT DATE_SUB('2025-02-09', 1); 结果:2025-02-08 |
DATEDIFF(enddate, startdate) | 计算两个日期之间的天数差。 | SELECT DATEDIFF('2025-02-10', '2025-02-09'); 结果:1 |
YEAR(date) | 提取日期中的年份部分。 | SELECT YEAR('2025-02-09'); 结果:2025 |
MONTH(date) | 提取日期中的月份部分。 | SELECT MONTH('2025-02-09'); 结果:2 |
DAY(date), DAYOFMONTH(date) | 提取日期中的日部分。 | SELECT DAY('2025-02-09'); 结果:9 |
HOUR(timestamp) | 提取时间戳中的小时部分(24小时制)。 | SELECT HOUR('2025-02-09 23:59:59'); 结果:23 |
MINUTE(timestamp) | 提取时间戳中的分钟部分。 | SELECT MINUTE('2025-02-09 23:59:59'); 结果:59 |
SECOND(timestamp) | 提取时间戳中的秒部分。 | SELECT SECOND('2025-02-09 23:59:59'); 结果:59 |
FROM_UNIXTIME(unix_timestamp, format) | 将Unix时间戳转换为日期时间格式。支持自定义输出格式。 | SELECT FROM_UNIXTIME(1676000000, 'yyyy-MM-dd HH:mm:ss'); |
UNIX_TIMESTAMP() , UNIX_TIMESTAMP(date) | 返回当前时间或指定日期的时间戳。默认返回当前时间的时间戳。 | SELECT UNIX_TIMESTAMP(); 或者 SELECT UNIX_TIMESTAMP('2025-02-09'); |
TO_DATE(timestamp) | 从时间戳中提取日期部分。 | SELECT TO_DATE('2025-02-09 23:59:59'); 结果:2025-02-09 |
LAST_DAY(date) | 返回给定日期所在月份的最后一天的日期。 | SELECT LAST_DAY('2025-02-09'); 结果:2025-02-28 |
4. 条件函数
条件函数用于根据特定条件执行不同的计算或返回不同的值。这些函数允许用户实现类似编程语言中的条件逻辑(如if-else语句),从而增强查询的灵活性和表达力。以下是几种常用的Hive条件函数及其功能的详细描述:
函数名称 | 描述 | 示例 |
---|---|---|
IF(condition, true_value, false_value) | 如果condition 为真,则返回true_value ;否则返回false_value 。 |
SELECT IF(1=1, 'Yes', 'No'); 结果:Yes |
COALESCE(col1, col2, ...) | 返回参数列表中第一个非空的值。如果所有参数都为NULL,则返回NULL。 | SELECT COALESCE(NULL, 'Value', 'Default'); 结果:Value |
CASE WHEN condition THEN result [ELSE else_result] END | 类似于编程语言中的switch-case结构,根据条件评估结果。可以包含多个WHEN子句,并且可以有一个可选的ELSE子句。 | SELECT CASE WHEN 1=1 THEN 'One' ELSE 'Other' END; 结果:One |
NVL(expr1, expr2) | 如果expr1 为NULL,则返回expr2 ;否则返回expr1 。注意:此函数是某些数据库系统特有的,在Hive中通常使用COALESCE 作为替代。 |
SELECT NVL(NULL, 'Fallback'); 结果:Fallback |
NULLIF(expr1, expr2) | 如果expr1 等于expr2 ,则返回NULL;否则返回expr1 。 |
SELECT NULLIF('A', 'A'); 结果:NULL |
5. 聚合函数
聚合函数用于对一组值执行计算并返回单一的汇总值。这些函数通常与GROUP BY
语句结合使用,以便于对数据进行分组和汇总分析。以下是一些常用的Hive聚合函数及其功能的详细描述:
函数名称 | 描述 | 示例 |
---|---|---|
COUNT(*) | 计算行数。如果使用COUNT(column) ,则仅计算非NULL值的行数。 |
SELECT COUNT(*) FROM table_name; 或 SELECT COUNT(column_name) FROM table_name; |
SUM(column) | 对某一列的所有非NULL值求和。 | SELECT SUM(salary) FROM employees; |
AVG(column) | 计算某一列所有非NULL值的平均值。 | SELECT AVG(salary) FROM employees; |
MIN(column) | 找出某一列中的最小值(忽略NULL值)。 | SELECT MIN(salary) FROM employees; |
MAX(column) | 找出某一列中的最大值(忽略NULL值)。 | SELECT MAX(salary) FROM employees; |
STDDEV(column) | 计算某一列的标准差(总体标准差)。对于样本标准差,可以使用STDDEV_SAMP() 。 |
SELECT STDDEV(salary) FROM employees; |
VARIANCE(column) | 计算某一列的方差(总体方差)。对于样本方差,可以使用VAR_SAMP() 。 |
SELECT VARIANCE(salary) FROM employees; |
COVAR_POP(x, y) | 计算两个变量x和y的总体协方差。 | SELECT COVAR_POP(x_column, y_column) FROM table_name; |
CORR(x, y) | 计算两个变量x和y的相关系数。 | SELECT CORR(x_column, y_column) FROM table_name; |
PERCENTILE(col, p) | 返回给定列col的第p百分位数值。p是一个介于0到1之间的数字。 | SELECT PERCENTILE(salary, 0.5) FROM employees; 结果:中位数 |
PERCENTILE_APPROX(col, p [, B]) | 近似计算给定列col的第p百分位数值。B是用于近似的桶数,默认为10000。适用于大数据集。 | SELECT PERCENTILE_APPROX(salary, 0.5, 10000) FROM employees; |
6. 集合函数
集合函数专门用于处理集合数据类型的函数,这些函数可以操作数组、映射和结构体等复杂数据类型。以下是一些常用的Hive集合函数及其功能描述:
函数名称 | 描述 | 示例 |
---|---|---|
SIZE(array) | 返回数组中的元素数量。对于映射类型,返回键值对的数量。 | SELECT SIZE(array_column) FROM table_name; |
ARRAY<type>(val1, val2, ...) | 创建一个包含给定元素的数组。 | SELECT ARRAY('a', 'b', 'c') AS my_array; 结果:["a","b","c"] |
MAP<key_type, value_type>(key1, value1, key2, value2, ...) | 创建一个映射(键值对)。 | SELECT MAP('name', 'John', 'age', 30) AS my_map; 结果:{"name":"John","age":30} |
SORT_ARRAY(array) | 对数组中的元素进行排序并返回排序后的数组。默认升序排列,可通过指定第二个参数为false 实现降序。 |
SELECT SORT_ARRAY(ARRAY(4, 2, 5, 1)) AS sorted_array; 结果:[1,2,4,5] |
ARRAY_CONTAINS(array, value) | 检查数组是否包含特定值,如果包含则返回true,否则返回false。 | SELECT ARRAY_CONTAINS(ARRAY('a', 'b', 'c'), 'b') AS contains_b; 结果:true |
MAP_KEYS(map) | 返回映射中的所有键组成的数组。 | SELECT MAP_KEYS(MAP('name', 'John', 'age', 30)) AS keys; 结果:["name","age"] |
MAP_VALUES(map) | 返回映射中的所有值组成的数组。 | SELECT MAP_VALUES(MAP('name', 'John', 'age', 30)) AS values; 结果:["John",30] |
INLINE(array_of_structs) | 展开由结构体组成的数组,将每个结构体的字段作为单独的列输出。注意,此函数通常与LATERAL VIEW 一起使用。 |
假设有一个表students ,其中一列是结构体数组,结构体包含name 和score 两个字段。 SELECT name, score FROM students LATERAL VIEW EXPLODE(struct_array_column) exploded_table AS name, score; 这个查询通过LATERAL VIEW 和EXPLODE 将结构体数组展开成多行,每一行对应结构体中的一个元素。请注意,虽然这里提到的是INLINE ,但在实际应用中更常用的是EXPLODE 结合LATERAL VIEW 来处理复杂数据类型。 |
7. 类型转换函数
类型转换函数用于将一种数据类型的值转换为另一种数据类型。这些函数对于处理来自不同来源的数据特别有用,因为它们可能具有不同的数据类型,或者需要根据特定的查询要求调整数据类型。以下是Hive中常用的类型转换函数及其功能描述:
函数名称 | 描述 | 示例 |
---|---|---|
CAST(expr AS type) | 将表达式expr 的结果转换为目标类型type 。支持多种类型间的转换,如从字符串转换为整数、日期等。 |
SELECT CAST('123' AS INT); 结果:123 SELECT CAST('2025-02-09' AS DATE); 结果:2025-02-09 |
FROM_UNIXTIME(unix_timestamp, format) | 将Unix时间戳(秒数)转换为指定格式的日期时间字符串。默认格式为'yyyy-MM-dd HH:mm:ss' 。 |
SELECT FROM_UNIXTIME(1676000000, 'yyyy-MM-dd HH:mm:ss'); |
UNIX_TIMESTAMP() , UNIX_TIMESTAMP(date) | 返回当前时间的时间戳或给定日期的时间戳。时间戳是以秒为单位的数值。 | SELECT UNIX_TIMESTAMP(); 或者 SELECT UNIX_TIMESTAMP('2025-02-09'); |
TO_DATE(timestamp) | 从时间戳中提取日期部分。返回格式为'yyyy-MM-dd' 。 |
SELECT TO_DATE('2025-02-09 23:59:59'); 结果:2025-02-09 |
DATE_FORMAT(date, fmt) | 按照指定的格式fmt 格式化日期date 。类似于Java中的SimpleDateFormat 格式化模式。 |
SELECT DATE_FORMAT('2025-02-09', 'yyyy/MM/dd'); 结果:2025/02/09 |
TRUNC(date, fmt) | 根据格式模型fmt 截断日期到指定的精度,如年、月、日等。 |
SELECT TRUNC('2025-02-09', 'MM'); 结果:2025-02-01 |
注意事项:
-
CAST : 是最基础也是最灵活的类型转换方式,几乎可以用于所有基本数据类型之间的转换,包括但不限于
INT
,BIGINT
,STRING
,FLOAT
,DOUBLE
,BOOLEAN
,TIMESTAMP
, 和DATE
。 -
FROM_UNIXTIME 和 UNIX_TIMESTAMP: 这两个函数专门用于处理Unix时间戳和标准日期时间字符串之间的转换。这对于需要与外部系统(如Unix/Linux环境)交互的应用非常有用。
-
DATE_FORMAT 和 TRUNC: 这些函数提供了对日期进行格式化和截断的能力,可以根据具体需求定制输出的日期格式或限制日期的精度。
8. 表生成函数 (UDTF)
表生成函数(User Defined Table-generating Functions, UDTF)用于将单个输入行转换为多行输出。这类函数特别适用于需要对复杂数据类型(如数组、映射或结构体)进行展开操作的场景。以下是一些常用的Hive内置UDTF及其功能描述:
函数名称 | 描述 | 示例 |
---|---|---|
EXPLODE(array_or_map) | 对于数组,EXPLODE 会为数组中的每个元素生成一行;对于映射,它会为每个键值对生成一行。通常与LATERAL VIEW 一起使用来简化查询。 |
SELECT * FROM src LATERAL VIEW EXPLODE(array_column) exploded_table AS col_name; |
INLINE(array_of_structs) | 展开由结构体组成的数组,将每个结构体的字段作为单独的列输出。注意,此函数通常与LATERAL VIEW 一起使用。 |
SELECT * FROM students LATERAL VIEW INLINE(struct_array_column) exploded_table AS name, score; |
POSEXPLODE(array_or_map) | 类似于EXPLODE ,但同时返回元素的位置索引和元素本身。对于数组,返回位置和元素;对于映射,返回位置、键和值。 |
SELECT * FROM src LATERAL VIEW POSEXPLODE(array_column) exploded_table AS pos, col_name; |
JSON_TUPLE(json_str, k1, k2, ...) | 从JSON字符串中提取多个键对应的值,并以元组形式返回。可以避免嵌套使用GET_JSON_OBJECT 。 |
SELECT JSON_TUPLE(json_column, 'key1', 'key2') AS (value1, value2) FROM table_name; |
SPLIT(string, regex) | 按照正则表达式分割字符串,返回一个数组。虽然严格意义上不是UDTF,但在结合LATERAL VIEW EXPLODE 时可以实现类似的效果。 |
SELECT * FROM src LATERAL VIEW EXPLODE(SPLIT(string_column, ',')) exploded_table AS word; |
示例:
-
使用
EXPLODE
:sqlSELECT student_id, subject FROM students LATERAL VIEW EXPLODE(subjects) exploded_table AS subject;
假设
students
表有一个名为subjects
的数组列,上述查询将每个学生的每个科目展开为独立的一行。 -
使用
POSEXPLODE
:sqlSELECT student_id, pos, subject FROM students LATERAL VIEW POSEXPLODE(subjects) exploded_table AS pos, subject;
这个查询不仅展开了
subjects
数组,还提供了每个科目的位置索引。 -
使用
JSON_TUPLE
:sqlSELECT id, json_tuple(info, 'name', 'age') as (name, age) FROM users;
假设
users
表有一个包含用户信息的JSON字符串列info
,上述查询从该列中提取name
和age
字段。 -
使用
SPLIT
与EXPLODE
组合:sqlSELECT word FROM sentences LATERAL VIEW EXPLODE(SPLIT(sentence, '\\s+')) exploded_table AS word;
此查询首先按空格分割句子,然后将得到的单词数组展开成多行。