【Hive】函数

UDF: 一进一出
UDAF: 多进一出
UDTF: 一进多出
(“多” 指的是输入数据的行数。)

一、系统内置函数

  • 查看系统自带的函数
show functions;
  • 显示自带的函数的用法
desc function upper;
  • 详细显示自带的函数的用法
desc function extended upper;

二、常用内置函数

空字段赋值 NVL

NVL(value,default_value)
给值为NULL的数据赋值。它的功能是如果value为NULL,则NVL函数返回default_value的值,否则返回value的值,如果两个参数都为NULL ,则返回NULL
(default_value可以是一个值,也可以是别的字段)

CASE WHEN THEN ELSE END

  • 需求:统计不同部门男女各多少人。结果应该如下图所示
    在这里插入图片描述
  • 查询语句:
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;

多列变一列(列转列)

1)CONCAT(string A/col, string B/col…): 返回输入字符串连接后的结果,支持任意个输入字符串;

2)CONCAT_WS(separator, str1, str2,…): 它是一个特殊形式的 CONCAT()。第一个参数是分隔符。分隔符可以是与剩余参数一样的字符串。如果分隔符是 NULL,返回值也将为 NULL。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。分隔符将被加到被连接的字符串之间;
注意: CONCAT_WS must be "string or array

3)COLLECT_SET(col): 函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段。(多进一出,udaf函数)
注意:COLLECT_LIST(col)则不去重汇总,也产生array类型字段

一行变多行(行转行)

  • EXPLODE(col): 将hive一列中复杂的array或者map结构拆分成多行。
    如:
    在这里插入图片描述
    查询:
select explode(split(category,',')) from movie_info;

将 category 中的多个词拆分,得到:
在这里插入图片描述

select movie, explode(split(category,‘,’)) from movie_info; 会报错

要加上 movie 列则需要用以下函数:

  • LATERAL VIEW
    LATERAL VIEW udtf(expression) tableAlias AS columnAlias
    用于和split, explode等UDTF一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。

查询:

SELECT 
	movie,category_name 
FROM movie_info 
LATERAL VIEW explode(split(category,",")) movie_info_tmp  AS category_name;

得到:
在这里插入图片描述

窗口函数

函数介绍

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

写在 over() 里面的函数,用来限定分组的行数:
CURRENT ROW: 当前行
n PRECEDING: 往前n行数据
n FOLLOWING: 往后n行数据
UNBOUNDED: 起点

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

写在 over() 前面的函数:
LAG(col,n,default_val): 往前第n行数据
LEAD(col,n, default_val): 往后第n行数据
NTILE(n):
把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。

按需求查询数据

原数据:
name,orderdate,cost
在这里插入图片描述

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

select name, count(*) over () 
from business 
where substring(orderdate,0,7) = '2017-04' 
group by name;

结果:
在这里插入图片描述

需求2:查询顾客的 购买明细 及 月购买总额

select name, orderdate, cost, sum(cost) over(partition by name, month(orderdate))
from business

月份函数month()

需求3:上述的场景, 将每个顾客的cost按照日期进行累加

写法一:

select name, orderdate, sum(cost) over(partition by name order by orderdate)
from business

写法二:

select name, orderdate, sum(cost) over(partition by name order by orderdate rows between unbounded preceding and current row)
from business

根据文档:When ORDER BY is specified with missing WINDOW clause, the WINDOW specification defaults to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

拓展:上述场景,将每个顾客的cost按照前一条、当前和后一条相加

select name, orderdate, sum(cost) over(partition by name order by orderdate rows between 1 preceding and 1 following)
from business

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

拓展:当排序值相同时:有一个只有一列 id 值的表,对其做以下查询

select id, sum(id) over(order by id)
from table1;

结果:
在这里插入图片描述
id值一样的,被认为是同一个窗口

需求4:查看顾客上次的购买时间

select name, orderdate, lag(orderdate,1, '1970-01-01') over(patition by name order by orderdate)
from business

需求5:查询前20%时间的订单信息

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

Rank

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

原数据:
在这里插入图片描述
需求:计算每门学科成绩排名

select *, rank() over(partition by subject order by score desc)
from score

扩展:求出每门学科前三名的学生

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

常用日期函数

unix_timestamp
from_unixtime
current_date
current_timestamp
to_date
year
month
day
hour
minute
second
weekofyear
dayofmonth
months_between
add_months
datediff
date_add
date_sub
last_day
date_format

常用取整函数

round:四舍五入
ceil:向上取整
floor:向下取整

常用字符串操作函数

upper
lower
length
trim
lpad
rpad
regexp_replace

集合操作

size
map_keys
map_values
array_contains
sort_array

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值