当前位置:   article > 正文

[大数据]Hive(4)_hive 4

hive 4

7 函数

7.1 系统内置函数

-- 查看系统自带的函数
hive> show functions;
-- 显示自带的函数的用法
hive> desc function upper;
-- 详细显示自带的函数的用法
hive> desc function extended upper;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7.2 其他常用查询函数

7.2.1 空字段赋值

函数说明
NVL:给值为NULL的数据赋值,它的格式是NVL( string1, replace_with)。它的功能是如果string1为NULL,则NVL函数返回replace_with的值,否则返回string1的值,如果两个参数都为NULL ,则返回NULL。

select * from emp
  • 1

在这里插入图片描述

select comm, nvl(comm, -1) from emp;
  • 1

在这里插入图片描述

7.2.2 CASE WHEN

数据准备
emp_sex.txt:

悟空	A	男
大海	A	男
宋宋	B	男
凤姐	A	女
婷姐	B	女
婷婷	B	女
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
--建表
create table emp_sex(
name string, 
dept_id string, 
sex string) 
row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/emp_sex.txt' into table emp_sex
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

-- 按需求查询数据
-- 统计不同部门男女各有多少人
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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

7.2.3 行转列

函数说明
CONCAT(string A/col, string B/col…):返回输入字符串连接后的结果,支持任意个输入字符串;
CONCAT_WS(separator, str1, str2,…):它是一个特殊形式的 CONCAT()。第一个参数剩余参数间的分隔符。分隔符可以是与剩余参数一样的字符串。如果分隔符是 NULL,返回值也将为 NULL。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。分隔符将被加到被连接的字符串之间;
COLLECT_SET(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段。

eg:需求,把星座和血型一样的人归类到一起

创建constellation.txt,导入数据

孙悟空	白羊座	A
大海	     射手座	A
宋宋	     白羊座	B
猪八戒    白羊座	A
凤姐	     射手座	A
  • 1
  • 2
  • 3
  • 4
  • 5
select * from person_info;
  • 1

在这里插入图片描述

-- 统计相同星座与血型共有多少人
select
	constellation,
	blood_type,
	count(*)
from
	person_info 
group by
	constellation,
	blood_type;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述
collect_list函数

-- 把同一组的人读成一个列表
select
	concat(constellation,",",blood_type) xzxx,
	collect_list(name)
from
	person_info 
group by 
	constellation, blood_type;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述
contact_ws:将列表里的函数拼接起来

select
	concat(constellation,",",blood_type) xzxx,
	concat_ws("|",collect_list(name))
from
	person_info 
group by 
	constellation, blood_type;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

7.2.4 列转行

函数说明
EXPLODE(col):将hive一列中复杂的array或者map结构拆分成多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:用于和split, explode等UDTF一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。

数据准备

movie	category
《疑犯追踪》	悬疑,动作,科幻,剧情
《Lie to me》	悬疑,警匪,动作,心理,剧情
《战狼2》	战争,动作,灾难
  • 1
  • 2
  • 3
  • 4

需求:
将电影中的数组数据展开,结果如下:

《疑犯追踪》      悬疑
《疑犯追踪》      动作
《疑犯追踪》      科幻
《疑犯追踪》      剧情
《Lie to me》   悬疑
《Lie to me》   警匪
《Lie to me》   动作
《Lie to me》   心理
《Lie to me》   剧情
《战狼2》        战争
《战狼2》        动作
《战狼2》        灾难

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

创建Hive表格并导入数据

create table movie_info(
    movie string, 
    category string) 
row format delimited fields terminated by "\t";
load data local inpath "/opt/module/datas/movie.txt" into table movie_info;
select * from movie_info
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

7.2.5 窗口函数

函数说明
OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
CURRENT ROW:当前行
n PRECEDING:往前n行数据
n FOLLOWING:往后n行数据
UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点
LAG(col,n,default_val):往前第n行数据
LEAD(col,n, default_val):往后第n行数据
NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。

数据准备:
business.txt:name,order,cost

jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

需求
(1)查询在2017年4月份购买过的顾客及总人数
(2)查询顾客的购买明细及月购买总额
(3)上述的场景, 将每个顾客的cost按照日期进行累加
(4)查询每个顾客上次的购买时间
(5)查询前20%时间的订单信息

创建表导入数据

create table business(name string, orderdata string, cost int)
row format delimited fields terminated by ',';
load data local inpath "/opt/module/datas/business.txt" into table business;
select * from business;
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
按需求查询数据

1.查询2017年4月否购买过东西的顾客

select distinct name
from business
where substring(orderdata, 1, 7) = "2017-04";
  • 1
  • 2
  • 3

在这里插入图片描述

select name, count(*) over()
from business 
where substring(orderdata, 1, 7) = "2017-04"
group by name;
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
2.查询顾客的购买明细以及月购买总额

select 
	name, cost, orderdata, 
	sum(cost) over(partition by substring(orderdata, 1, 7))
from business;
  • 1
  • 2
  • 3
  • 4

按照月份进行加和
在这里插入图片描述
3.上述的场景, 将每个顾客的cost按照日期进行累加

select name,orderdate,cost, 
sum(cost) over() as sample1,--所有行相加 
sum(cost) over(partition by name) as sample2,--按name分组,组内数据相加 
sum(cost) over(partition by name order by orderdate) as sample3,--按name分组,组内数据累加 
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一样,由起点到当前行的聚合 
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --当前行和前面一行做聚合 
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--当前行和前边一行及后面一行 
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --当前行及后面所有行 
from business;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述
查询每个月来的顾客以及明细

select name,orderdata,cost, 
concat_ws(",",collect_set(name)
over(partition by substring (orderdata, 1, 7)))
from business;
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
在这里插入图片描述
查询每个顾客上次(下次)的购买时间

--lag lead
select 
	name, orderdata, cost,
	lag(orderdata, 1 ,"1970-01-01") 
	over(partition by name order by orderdata) last_order,
	lead(orderdata, 1 ,"1970-01-01") 
	over(partition by name order by orderdata) next_order 
from business ;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述
查询前20%时间的订单信息

-- ntail
select * from (
    select name,orderdate,cost, ntile(5) over(order by orderdate) sorted
    from business
	) t
where sorted = 1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
百分比

-- percent_rank
select
	name, orderdata, cost,
	percent_rank() over(order by orderdata) pr
from
	business;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

7.2.6 排序

函数说明
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算

新建文件 score.txt

孙悟空  语文    87
孙悟空  数学    95
孙悟空  英语    68
大海    语文    94
大海    数学    56
大海    英语    84
宋宋    语文    64
宋宋    数学    86
宋宋    英语    84
婷婷    语文    65
婷婷    数学    85
婷婷    英语    78
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

需求:
计算每门学科成绩排名。

--创建表并导入数据
create table score(
	name string,
	subject string, 
	score int) 
row format delimited fields terminated by "\t";

load data local inpath '/opt/module/datas/score.txt' into table score;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

按需求查询数据

-- rank() dense_rank() row_number()
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) rmp
from score;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

7.2.7 日期相关函数

1.当前日期

select current_date();
  • 1

2.日期加减

--今天开始90天以后的日期
select date_add(current_date(), 90);
--今天开始90天以前的日期
select date_sub(current_date(), 90);
  • 1
  • 2
  • 3
  • 4

3.两个日期之间的日期差

--今天和1990年1月1日的天数差
select datediff(current_date(), "1990-01-01");
  • 1
  • 2
--有哪些顾客连续两天有消费
--先排号
--求日期相减
--求连续两天来过的

select 
	name,temp,
	count(*) c
from
	(select
	*,
	date_sub(orderdata, rn) temp
	from 
		(select
		*,
		row_number() over(partition by name order by orderdata) rn
		from business) t1) t2
group by
	name,temp
having c>=2;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

7.3 自定义UDF函数

1)创建一个Maven工程Hive
2)导入依赖

<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
		<dependency>
			<groupId>org.apache.hive</groupId>
			<artifactId>hive-exec</artifactId>
			<version>3.1.2</version>
		</dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3)创建类
(老接口)

package com.atguigu.hive;
import org.apache.hadoop.hive.ql.exec.UDF;

/**
 * 老接口,给一个字符串,返回长度
 */
public class MyUDF extends UDF {
    public int evaluate(String input) {
        if (input == null) return 0;
        return input.length();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(新接口)实现类型检查器

package com.atguigu.hive;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

/**
 * 给一个字符串,返回长度
 */
public class MyUDF extends GenericUDF {
    /**
     * 对输入的方法做检查,以及约束输出的类型
     *
     * @param objectInspectors 输入参数的检查器
     * @return 输出参数的检查器
     * @throws UDFArgumentException
     */
    @Override
    public ObjectInspector initialize(ObjectInspector[] objectInspectors) throws UDFArgumentException {
        if (objectInspectors.length != 1) {
            throw new UDFArgumentLengthException("Wrong arguments count");
        }
        if (!objectInspectors[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)) {
            throw new UDFArgumentTypeException(0, "Wrong argument type");
        }
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    /**
     * 实现逻辑
     *
     * @param deferredObjects
     * @return
     * @throws HiveException
     */
    @Override
    public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
        Object o = deferredObjects[0].get();
        if (o == null) return 0;
        return o.toString().length();
    }

    /**
     * 函数执行出错 错误提示
     * @param strings
     * @return
     */
    @Override
    public String getDisplayString(String[] strings) {
        return null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

4)jar包上传到服务器/opt/module/hive/lib
5)jar包添加到hive的classpath

add jar /opt/module/hive/lib/hiveplugin20210506-1.0
  • 1

6)创建临时函数与开发好的java class关联

create temporary function my_len as "com.atguigu.hive.MyUDF"
  • 1

7)测试使用函数

select name, my_len(name) from business;
  • 1

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/833666
推荐阅读
相关标签
  

闽ICP备14008679号