深度总结:Hive函数快速入门指南

一、函数概述

如同RDBMS中标准SQL语法一样,Hive SQL也内建了不少函数,满足于用户在不同场合下的数据分析需求,提高开发SQL数据分析的效率。

可以使用show functions查看当下版本支持的函数,并且可以通过describe function extended funcname来查看函数的使用方式和方法。

二、函数分类概述

Hive的函数很多,除了自己内置所支持的函数之外,还支持用户自己定义开发函数。

针对 内置的函数,可以根据函数的应用类型进行归纳分类,比如:数值类型函数、日期类型函数、字符串类型函数、集合函数、条件函数等;

针对 用户自定义函数,可以根据函数的输入输出行数进行分类,比如:UDF、UDAF、UDTF。

三、内置函数分类

所谓的 内置函数(buildin) 指的是Hive开发实现好,直接可以使用的函数,也叫做内建函数。

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

内置函数根据应用归类整体可以分为以下8大种类型,我们将对其中重要的,使用频率高的函数使用进行详细讲解。

String Functions 字符串函数

字符串函数主要用于对字符串数据类型进行各种操作,涵盖了从基础的字符处理到复杂的文本解析,以下为常见的字符串函数:

  • 长度计算length,用于获取字符串的长度,以准确知晓字符串包含的字符数量。
  • 字符顺序调整reverse,能够将字符串中的字符顺序进行反转,满足特定文本处理需求。
  • 字符串拼接
    • concat,直接将多个字符串连接成一个字符串,实现简单的文本合并。
    • concat_ws,在连接字符串时,可以指定一个分隔符,让拼接后的字符串更具格式规范性。
  • 字符提取与截取substrsubstring 功能一致,可从字符串中按照指定的起始位置和长度进行截取,提取所需的子字符串。
  • 大小写转换
    • upperucase 均可将字符串中的所有字符转换为大写形式,便于统一文本格式。
    • lowerlcase 则用于将字符串中的字符全部转换为小写,同样用于文本格式的规范化处理。
  • 空白字符处理
    • trim,能够去除字符串两端的空白字符,使文本更加整洁。
    • ltrim,专门去除字符串左边(开头)的空白字符。
    • rtrim,用于去除字符串右边(末尾)的空白字符。
  • 文本模式匹配与替换
    • regexp_replace,依据正则表达式对字符串中的特定模式进行匹配,并将匹配到的内容替换为指定字符串,实现复杂文本替换操作。
    • regexp_extract,通过正则表达式从字符串中提取符合特定模式的子字符串,助力精准的文本解析。
  • 特殊格式解析
    • parse_url,专门用于解析URL字符串,提取其中的各个组成部分,如协议、域名、路径等。
    • get_json_object,用于从JSON格式的字符串中提取指定的JSON对象或值,方便处理JSON数据。
  • 特定字符串生成
    • space,生成指定数量的空格组成的字符串,可用于格式化文本输出。
    • repeat,将指定字符串重复指定次数,以满足特定的文本生成需求。
  • 字符编码获取ascii,返回字符串首字符的ASCII码值,用于了解字符的编码信息。
  • 字符串填充
    • lpad,在字符串左边填充指定字符,使字符串达到指定长度,常用于数据格式化。
    • rpad,在字符串右边填充指定字符,同样用于满足特定长度要求的数据格式化场景。
  • 字符串分割与集合查找
    • split,按照指定的分隔符将字符串分割成字符串数组,便于对文本进行细粒度处理。
    • find_in_set,在指定的集合中查找特定字符串的位置,适用于处理包含集合数据的场景。
------------String Functions 字符串函数------------
describe function extended find_in_set;

--字符串长度函数:length(str | binary)
select length("angelababy");

--字符串反转函数:reverse
select reverse("angelababy");

--字符串连接函数:concat(str1, str2, ... strN)
select concat("angela","baby");

--带分隔符字符串连接函数:concat_ws(separator, [string | array(string)]+)
select concat_ws('.', 'www', array('itcast', 'cn'));

--字符串截取函数:substr(str, pos[, len]) 或者  substring(str, pos[, len])
select substr("angelababy",-2); --pos是从1开始的索引,如果为负数则倒着数
select substr("angelababy",2,2);

--字符串转大写函数:upper,ucase
select upper("angelababy");
select ucase("angelababy");

--字符串转小写函数:lower,lcase
select lower("ANGELABABY");
select lcase("ANGELABABY");

--去空格函数:trim 去除左右两边的空格
select trim(" angelababy ");

--左边去空格函数:ltrim
select ltrim(" angelababy ");

--右边去空格函数:rtrim
select rtrim(" angelababy ");

--正则表达式替换函数:regexp_replace(str, regexp, rep)
select regexp_replace('100-200', '(\\d+)', 'num');

--正则表达式解析函数:regexp_extract(str, regexp[, idx]) 提取正则匹配到的指定组内容
select regexp_extract('100-200', '(\\d+)-(\\d+)', 2);

--URL解析函数:parse_url 注意要想一次解析出多个 可以使用parse_url_tuple这个UDTF函数
select parse_url('http://www.itcast.cn/path/p1.php?query=1', 'HOST');

--json解析函数:get_json_object
--空格字符串函数:space(n) 返回指定个数空格
select space(4);

--重复字符串函数:repeat(str, n) 重复str字符串n次
select repeat("angela",2);

--首字符ascii函数:ascii
select ascii("angela");  --a对应ASCII 97

--左补足函数:lpad
select lpad('hi', 5, '??');  --???hi
select lpad('hi', 1, '??');  --h

--右补足函数:rpad
select rpad('hi', 5, '??');

--分割字符串函数: split(str, regex)
select split('apache hive', '\\s+');

--集合查找函数: find_in_set(str,str_array)
select find_in_set('a','abc,b,ab,c,def');

Date Functions 日期函数

日期函数主要用于对时间和日期数据类型进行各类操作,涵盖从时间获取、格式转换到日期抽取、运算等多个方面,常见的日期函数如下:

  • 当前时间获取
    • current_date:用于获取当前日期,以简洁的格式返回当天的日期信息,方便记录和处理与当日相关的数据。
    • current_timestamp:获取当前时间戳,精确到毫秒级,包含了日期和时间的完整信息,适用于对时间精度要求较高的场景,如日志记录时间点。
  • 时间戳与日期转换
    • from_unixtime:将UNIX时间戳转换为日期格式,能够把以秒为单位的时间戳转换为人类可读的日期时间格式,便于数据展示和分析。
    • unix_timestamp:此函数具有多种功能。它可以获取当前UNIX时间戳,为系统提供当前时间的数值表示;也能将日期转成UNIX时间戳,实现日期到时间戳的转换;还能针对指定格式的日期进行UNIX时间戳转换,满足不同格式日期的处理需求。
  • 日期抽取与解析
    • to_date:从包含日期时间的字符串或表达式中抽取日期部分,去除时间信息,仅保留日期,方便进行日期相关的统计和分析。
    • year:从日期中提取年份,返回一个四位数的年份值,常用于按年份进行数据统计和分组。
    • month:提取日期中的月份,以数字1 - 12表示,有助于按月份进行数据分析和报表生成。
    • day:获取日期中的日,即一个月中的第几天,用于精确的日期定位和计算。
    • hour:从时间中抽取小时数,取值范围为0 - 23,对于分析时间序列数据中每小时的变化情况非常有用。
    • minute:提取时间中的分钟数,取值范围是0 - 59,帮助细化时间分析粒度。
    • second:获取时间中的秒数,同样取值范围为0 - 59,用于需要精确到秒的时间处理场景。
    • weekofyear:计算日期是一年中的第几周,便于进行按周的数据分析和统计。
  • 日期运算与比较
    • datediff:用于比较两个日期之间的差值,以天数为单位返回结果,方便计算时间间隔,如计算两个事件之间相隔的天数。
    • date_add:在指定日期上增加一定的时间间隔,可增加天数、月数、年数等,用于预测未来日期或计算到期时间。
    • date_sub:与date_add相反,在指定日期上减去一定的时间间隔,用于追溯过去的日期或计算历史时间点。
--获取当前日期: current_date
select current_date();

--获取当前时间戳: current_timestamp
--同一查询中对current_timestamp的所有调用均返回相同的值。
select current_timestamp();

--获取当前UNIX时间戳函数: unix_timestamp
select unix_timestamp();

--UNIX时间戳转日期函数: from_unixtime
select from_unixtime(1618238391);
select from_unixtime(0, 'yyyy-MM-dd HH:mm:ss');

--日期转UNIX时间戳函数: unix_timestamp
select unix_timestamp("2011-12-07 13:01:03");

--指定格式日期转UNIX时间戳函数: unix_timestamp
select unix_timestamp('20111207 13:01:03','yyyyMMdd HH:mm:ss');

--抽取日期函数: to_date
select to_date('2009-07-30 04:17:52');

--日期转年函数: year
select year('2009-07-30 04:17:52');

--日期转月函数: month
select month('2009-07-30 04:17:52');

--日期转天函数: day
select day('2009-07-30 04:17:52');

--日期转小时函数: hour
select hour('2009-07-30 04:17:52');

--日期转分钟函数: minute
select minute('2009-07-30 04:17:52');

--日期转秒函数: second
select second('2009-07-30 04:17:52');

--日期转周函数: weekofyear 返回指定日期所示年份第几周
select weekofyear('2009-07-30 04:17:52');

--日期比较函数: datediff  日期格式要求'yyyy-MM-dd HH:mm:ss' or 'yyyy-MM-dd'
select datediff('2012-12-08','2012-05-09');

--日期增加函数: date_add
select date_add('2012-02-28',10);

--日期减少函数: date_sub
select date_sub('2012-01-1',10);

Mathematical Functions 数学函数

数学函数主要用于对数值类型的数据执行各类数学运算,从基础的数值处理到复杂的数值转换,这些函数为数据处理和分析提供了强大的数学支持,常见的数学函数如下:

  • 数值取整
    • round:具有两种功能,一是常规的取整操作,将数值按照四舍五入的规则转换为最接近的整数;二是可以指定精度进行取整,通过指定小数位数,对数值进行精确的舍入处理,满足不同场景下对数值精度的要求。
    • floor:执行向下取整操作,无论小数部分是多少,都将数值直接向下取整为小于或等于该数值的最大整数,常用于需要舍弃小数部分的场景。
    • ceil:进行向上取整,即无论小数部分的值如何,都将数值向上取整为大于或等于该数值的最小整数,适用于需要进位处理的计算场景。
  • 随机数生成rand,用于生成一个介于0(包括)和1(不包括)之间的随机小数。在模拟实验、随机抽样等场景中,这个函数能够为数据处理引入随机性,满足多样化的数据分析需求。
  • 数值进制转换
    • bin:将十进制数值转换为二进制表示形式,以字符串的形式返回对应的二进制数,方便进行位运算或与二进制相关的操作。
    • conv:这是一个更为通用的进制转换函数,可以将一个数值在不同进制之间进行转换,通过指定源进制和目标进制,实现数值在多种进制体系下的灵活转换,满足特定的数据处理和算法要求。
  • 数值基本运算abs,计算并返回一个数值的绝对值,无论输入的数值是正数还是负数,都返回其正值,常用于计算距离、误差等只关注数值大小而不考虑正负方向的场景。
--取整函数: round  返回double类型的整数值部分 (遵循四舍五入)
select round(3.1415926);

--指定精度取整函数: round(double a, int d) 返回指定精度d的double类型
select round(3.1415926,4);

--向下取整函数: floor
select floor(3.1415926);
select floor(-3.1415926);

--向上取整函数: ceil
select ceil(3.1415926);
select ceil(-3.1415926);

--取随机数函数: rand 每次执行都不一样 返回一个0到1范围内的随机数
select rand();

--指定种子取随机数函数: rand(int seed) 得到一个稳定的随机数序列
select rand(2);

--二进制函数:  bin(BIGINT a)
select bin(18);

--进制转换函数: conv(BIGINT num, int from_base, int to_base)
select conv(17,10,16);

--绝对值函数: abs
select abs(-3.9);

Collection Functions 集合函数

集合函数主要用于对集合这种复杂数据类型进行各类操作,通过这些函数可以高效地处理和分析集合中的数据,常见的集合函数如下:

  • 集合元素数量统计size,该函数可用于计算集合的元素数量。对于Map<K, V>类型的集合,它返回键值对的数量;对于Array<T>类型的数组,它返回数组中元素的个数,方便了解集合的规模大小。
  • Map集合关键信息提取
    • map_keys,专门用于提取Map<K, V>集合中的所有键(Key),并以集合的形式返回,在需要单独处理Map集合的键时非常实用。
    • map_values,用于获取Map<K, V>集合中的所有值(Value),同样以集合形式返回,方便对Map集合的值进行统一处理和分析。
  • 数组元素判断array_contains,用于判断一个数组Array<T>中是否包含指定元素value。如果数组包含该元素,则返回true;否则返回false,常用于快速查找数组中是否存在特定元素的场景。
  • 数组排序sort_array,对Array<T>类型的数组进行排序。它会按照数组元素的自然顺序(如数字从小到大、字符串按字典序)对数组中的元素进行排列,以便于后续的数据处理和分析,提高数据的有序性和可读性。
--集合元素size函数: size(Map<K.V>) size(Array<T>)
select size(`array`(11,22,33));
select size(`map`("id",10086,"name","zhangsan","age",18));

--取map集合keys函数: map_keys(Map<K.V>)
select map_keys(`map`("id",10086,"name","zhangsan","age",18));

--取map集合values函数: map_values(Map<K.V>)
select map_values(`map`("id",10086,"name","zhangsan","age",18));

--判断数组是否包含指定元素: array_contains(Array<T>, value)
select array_contains(`array`(11,22,33),11);
select array_contains(`array`(11,22,33),66);

--数组排序函数:sort_array(Array<T>)
select sort_array(`array`(12,2,32));

Conditional Functions 条件函数

条件函数主要应用于需要进行条件判断、逻辑判断以及数据转换的场景,通过这些函数能够实现数据的筛选、处理以及异常情况的处理,以下为常见的条件函数:

  • 基础条件判断if,这是一个常用的条件判断函数,语法为if(boolean testCondition, T valueTrue, T valueFalseOrNull)。它会根据传入的布尔型测试条件testCondition进行判断,如果条件为真,返回valueTrue;若条件为假,则返回valueFalseOrNull,常用于根据不同条件返回不同结果的逻辑处理。
  • 空值判断与处理
    • isnull,用于判断输入值a是否为空值。如果a为空,返回true;否则返回false,便于在数据处理中识别空值情况。
    • isnotnull,与isnull相反,用于判断输入值a是否为非空值。若a不为空,返回true;否则返回false,帮助进行非空值的逻辑判断。
    • nvl,空值转换函数,语法为nvl(T value, T default_value)。当value为空值时,返回default_value;若value不为空,则返回value本身,有效避免空值对数据处理的影响。
    • COALESCE,非空查找函数,语法为COALESCE(T v1, T v2,...)。它会从左到右依次检查参数列表中的值,返回第一个非空值。如果所有参数都为空,则返回null,常用于在多个可能为空的值中获取第一个可用值。
  • 复杂条件转换CASE,条件转换函数,语法为CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END。它首先对a进行求值,然后依次将其与WHEN子句中的值进行比较。如果a等于b,则返回c;若等于d,返回e,以此类推。若所有WHEN条件都不满足,则返回ELSE子句中的f。若没有ELSE子句且所有条件都不匹配,则返回null,适用于复杂的多条件数据转换场景。
  • 特殊条件判断
    • nullif,语法为nullif( a, b )。当a等于b时,返回null;否则返回a。该函数常用于需要对比两个值并在相等时返回特定结果的场景。
    • assert_true,用于条件断言。如果传入的condition不为真,会引发异常;若条件为真,则返回null,主要用于在程序执行过程中确保某些条件的正确性,避免潜在错误。
--使用之前课程创建好的student表数据
select * from student limit 3;

--if条件判断: if(boolean testCondition, T valueTrue, T valueFalseOrNull)
select if(1=2,100,200);
select if(sex ='男','M','W') from student limit 3;

--空判断函数: isnull( a )
select isnull("allen");
select isnull(null);

--非空判断函数: isnotnull ( a )
select isnotnull("allen");
select isnotnull(null);

--空值转换函数: nvl(T value, T default_value)
select nvl("allen","itcast");
select nvl(null,"itcast");

--非空查找函数: COALESCE(T v1, T v2, ...)
--返回参数中的第一个非空值;如果所有值都为NULL,那么返回NULL
select COALESCE(null,11,22,33);
select COALESCE(null,null,null,33);
select COALESCE(null,null,null);

--条件转换函数: CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END
select case 100 when 50 then 'tom' when 100 then 'mary' else 'tim' end;
select case sex when '男' then 'man' else 'women' end from student limit 3;

--nullif( a, b ):
-- 果a = b,则返回NULL;否则返回NULL。否则返回一个
select nullif(11,11);
select nullif(11,12);

--assert_true(condition)
--如果'condition'不为真,则引发异常,否则返回null
SELECT assert_true(11 >= 0);
SELECT assert_true(-1 >= 0);

Type Conversion Functions 类型转换函数

主要用于显式的数据类型转换,有下面两种函数:

•任意数据类型之间转换:cast
--任意数据类型之间转换:cast
select cast(12.14 as bigint);
select cast(12.14 as string);

Data Masking Functions 数据脱敏函数

数据脱敏函数的核心作用是对原始数据进行脱敏转换,通过特定算法和规则,将敏感信息进行隐藏或变形,从而在保障数据可用性的同时,确保数据的安全性,防止敏感数据泄露。常见的数据脱敏函数如下:

  • 通用脱敏函数mask,它是一个基础的数据脱敏函数,能够依据既定的脱敏策略对输入数据进行处理,适用于多种数据类型和场景,以统一的方式对原始数据进行屏蔽,使敏感信息不可见。
  • 特定位置字符脱敏函数
    • mask_first_n(string str[, int n]),用于对字符串str的前n个字符进行脱敏处理。函数会将前n个字符替换为特定的掩码字符(如星号*),而字符串的其余部分保持不变,常用于保护如姓名、账号等信息的开头部分。
    • mask_last_n(string str[, int n]),与mask_first_n相反,该函数对字符串str的后n个字符进行脱敏。将后n个字符替换为掩码字符,适用于保护数据的末尾部分,例如银行卡号的后几位。
  • 特定位置字符保留显示脱敏函数
    • mask_show_first_n(string str[, int n]),在对字符串进行脱敏时,保留前n个字符的原始内容显示,其余部分则用掩码字符替代 。这样既保留了部分关键信息,又对敏感部分进行了隐藏,常用于显示部分账号、姓名等信息。
    • mask_show_last_n(string str[, int n]),保留字符串str的后n个字符原始内容显示,其余部分进行脱敏处理,满足一些需要展示末尾部分关键信息,同时隐藏其他敏感内容的场景。
  • 哈希脱敏函数mask_hash(string|char|varchar str),通过哈希算法对输入的字符串str进行处理,将原始数据转换为不可逆的哈希值。哈希值具有唯一性,且无法通过反向计算还原原始数据,适用于对密码等高度敏感数据的脱敏存储,确保数据在存储和传输过程中的安全性。
--mask
--将查询回的数据,大写字母转换为X,小写字母转换为x,数字转换为n。
select mask("abc123DEF");
select mask("abc123DEF",'-','.','^'); --自定义替换的字母

--mask_first_n(string str[, int n]
--对前n个进行脱敏替换
select mask_first_n("abc123DEF",4);

--mask_last_n(string str[, int n])
select mask_last_n("abc123DEF",4);

--mask_show_first_n(string str[, int n])
--除了前n个字符,其余进行掩码处理
select mask_show_first_n("abc123DEF",4);

--mask_show_last_n(string str[, int n])
select mask_show_last_n("abc123DEF",4);

--mask_hash(string|char|varchar str)
--返回字符串的hash编码。
select mask_hash("abc123DEF");

Misc. Functions 其他杂项函数

这一类函数涵盖了多种不同功能,在数据处理、系统信息获取以及数据加密等方面发挥着独特作用,具体如下:

  • Java方法调用java_method(class, method[, arg1[, arg2..]]),通过该函数,Hive能够调用Java类中的方法。只需指定对应的Java类名class、方法名method以及所需的参数arg1arg2等,即可实现Hive与Java代码的交互,借助Java丰富的类库和功能,拓展Hive的数据处理能力。
  • 反射函数reflect(class, method[, arg1[, arg2..]]),利用反射机制,在运行时动态地获取类信息并调用其方法。同样通过指定类名class和方法名method以及参数列表,该函数可以在不预先知道类和方法的情况下,灵活地调用Java类中的方法,为数据处理提供了更强大的动态性和灵活性。
  • 哈希值计算hash,用于计算输入数据的哈希值。它能够对各种类型的数据进行处理,生成一个固定长度的哈希值,常用于数据校验、数据索引等场景,确保数据的完整性和唯一性。
  • 系统信息获取
    • current_user(),返回当前登录用户的用户名,方便在数据处理过程中进行用户身份识别和权限控制。
    • logged_in_user(),同样用于获取当前登录用户信息,与current_user()类似,为系统提供用户相关的上下文信息。
    • current_database(),返回当前正在使用的数据库名称,在多数据库环境中,明确当前操作所处的数据库,便于数据管理和操作。
    • version(),返回Hive的版本信息,有助于了解系统的特性和兼容性,方便进行版本管理和问题排查。
  • 加密算法函数
    • SHA - 1加密sha1(string/binary),采用SHA - 1加密算法对输入的字符串或二进制数据进行加密。该算法生成一个160位的哈希值,常用于对数据进行安全哈希处理,以保证数据的完整性和安全性,尽管其安全性在现代环境下存在一定风险,但仍在部分场景中使用。
    • SHA - 2家族算法加密sha2(string/binary, int),支持SHA - 224、SHA - 256、SHA - 384、SHA - 512等多种SHA - 2系列加密算法。通过第二个参数int来指定具体的算法类型,对输入数据进行更安全、更强大的加密处理,广泛应用于对数据安全性要求较高的场景。
    • MD5加密md5(string/binary),运用MD5加密算法对数据进行加密,生成一个128位的哈希值。MD5曾经被广泛应用于数据加密和校验,但随着安全技术的发展,其安全性逐渐受到质疑,不过在一些对安全性要求不特别高的场景中仍有使用。
    • crc32加密:用于计算循环冗余校验码(CRC32),主要用于检测数据传输或存储过程中的错误,通过对数据进行特定计算生成一个32位的校验码,接收方可以通过重新计算CRC32值来验证数据的完整性,虽不属于严格意义上的加密算法,但在数据完整性保障方面发挥重要作用。
--hive调用java方法: java_method(class, method[, arg1[, arg2..]])
select java_method("java.lang.Math","max",11,22);

--反射函数: reflect(class, method[, arg1[, arg2..]])
select reflect("java.lang.Math","max",11,22);

--取哈希值函数:hash
select hash("allen");

--current_user()、logged_in_user()、current_database()、version()

--SHA-1加密: sha1(string/binary)
select sha1("allen");

--SHA-2家族算法加密:sha2(string/binary, int)  (SHA-224, SHA-256, SHA-384, SHA-512)
select sha2("allen",224);
select sha2("allen",512);

--crc32加密:
select crc32("allen");

--MD5加密: md5(string/binary)
select md5("allen");

四、用户自定义函数分类

Hive虽内置大量丰富的函数,然而面对用户千差万别的分析需求与复杂多样的应用场景,这些内置函数未必总能满足。为有效解决这一问题,Hive推出了用户自定义函数功能,使用户能够根据自身特定需求,自主实现期望的功能函数,极大地拓展了Hive的数据处理能力。

用户自定义函数,英文简称为UDF,即user - defined function。按照函数输入输出的行数差异,自定义函数总共可分为3类:

  • UDF(User-Defined-Function)普通函数:这类函数的特点是“一进一出”,即输入一行数据,经过函数处理后输出一行数据。它常用于对数据进行简单的格式转换、计算等操作,例如对字符串进行大小写转换、对数值进行简单的数学运算等。
  • UDAF(User-Defined Aggregation Function)聚合函数:呈现“多进一出”的特性,需要输入多行数据,然后对这些数据进行聚合计算,最终输出一行结果。常见的聚合操作如求和、求平均值、求最大值等都可以通过UDAF来实现,在数据统计分析中发挥着重要作用。
  • UDTF(User-Defined Table-Generating Functions)表生成函数:其显著特征是“一进多出”,输入一行数据,却能生成多行数据或多个列,常用于将复杂的数据结构展开,比如将一个包含多个元素的数组拆分成多行,以便进行更细致的数据处理和分析。

UDF分类标准扩大化

通常我们所说的UDF是指用户编写开发的函数,但其分类标准并非局限于此,实际上可以拓展应用到Hive的所有函数,包括内置函数和自定义函数。这是因为任何函数在执行过程中,必然要满足输入输出的要求。从输入行数和输出行数的角度进行划分,具有普适性和合理性。大家在理解和运用时,切勿仅仅因为“UD(User-Defined)”这两个字母,就将思维局限于用户自定义函数本身,而应从更宏观的视角去认识和应用这一分类体系,从而更全面、灵活地运用Hive函数进行数据处理和分析。

比如Hive官方文档中,针对聚合函数的标准就是内置的UDAF类型。

4.1.UDF 普通函数

UDF函数通常把它叫做普通函数,最大的特点是一进一出,也就是输入一行输出一行。比如round这样的取整函数,接收一行数据,输出的还是一行数据。

4.2.UDAF 聚合函数

UDAF,全称User - Defined Aggregation Function,通常被称作聚合函数,其中“A”代表“Aggregation”,即“聚合”之意。这类函数最为显著的特点是“多进一出”,也就是输入多行数据,最终输出一行结果 。像我们常见的countsum等函数,都属于UDAF的范畴。具体介绍如下:

  • count:用于统计检索到的总行数,能够快速准确地告知数据集中的记录数量,在数据统计和分析中是基础且常用的函数,可帮助了解数据规模。
  • sum:执行求和操作,将输入的多行数值数据进行累加,得出总和,在财务数据统计、数量汇总等场景中频繁使用。
  • avg:用于计算平均值,它先对输入的多行数值数据进行求和,再除以数据的行数,从而得出这些数据的平均值,常用于分析数据的集中趋势。
  • min:在输入的多行数据中找出最小值,能直观反映数据集中的下限,在对比分析、极值查找等场景发挥作用。
  • max:与min相反,从输入的多行数据中找出最大值,展示数据集中的上限,同样在各类数据分析场景中至关重要。
  • collect_set(col):这是一个数据收集函数,且具备去重功能。它会将指定列col中的数据收集起来,并去除其中的重复值,最终以集合的形式返回,在需要获取某列去重后的数据集合时非常实用。
  • collect_list(col):也是数据收集函数,但此函数不会对数据进行去重。它会将指定列col中的所有数据按照顺序收集起来,以列表的形式返回,适用于需要保留所有数据顺序和重复值的场景。
select sex from student;

select collect_set(sex) from student;
select collect_list(sex) from student;

4.3.UDTF 表生成函数

UDTF函数通常把它叫做表生成函数,T所代表的单词是Table-Generating表生成的意思。最大的特点是一进多出,也就是输入一行输出多行。

之所以叫做表生成函数,原因在于这类型的函数作用返回的结果类似于表(多行数据嘛),同时,UDTF函数也是我们接触比较少的函数,陌生。比如explode函数。

文章来源: https://study.disign.me/article/202508/8.hive-functions-quick-guide.md

发布时间: 2025-02-20

作者: 技术书栈编辑