Hive笔记

news2024/12/28 19:19:41

目录

第3章 Hive数据类型

第 4 章 DDL 数据定义

第5章DML数据操作

第6章 查询(语法与MySQL一样)

第 7 章 分区表和分桶表

第 8 章 函数


第3章 Hive数据类型

如array<map<string,int>>

集合数据类型工作中不是很常用,最常用的就是基本数据类型中的INT、BIGINT、BOOLEAN、DOUBLE、STRING这五种。其中日期类型也不常用,因为哪怕是字符串类型写成yyyy-mm-nn年月日的形式,都可以自动转换成日期形式。

1)集合案例实操 (了解即可)

1)假设某表有如下一行,我们用 JSON 格式来表示其数据结构。在 Hive 下访问的格

式为

{

"name": "songsong",

"friends": ["bingbing" , "lili"] , //列表 Array,

"children": { //键值 Map,

"xiao song": 18 ,

"xiaoxiao song": 19

}

"address": { //结构 Struct,

"street": "hui long guan",

"city": "beijing"

}

}

(2)Hive 上创建测试表 test

create table test(

name string,

friends array<string>,

children map<string, int>,

address struct<street:string, city:string>

)

row format delimited fields terminated by ','

collection items terminated by '_'

map keys terminated by ':'

lines terminated by '\n';

字段解释:

row format delimited fields terminated by ',' -- 列分隔符

collection items terminated by '_'  -- MAPSTRUCT ARRAY 的元素分隔符(数据分割符号)

map keys terminated by ':' -- MAP 中的 key value 的分隔符

lines terminated by '\n'; -- 行分隔符(默认是\n,所以这行可写可不写)

访问方式:select friends[0],children[xiaosong],address.street from test;

数组:通过下标访问 map:通过传入key访问value    struct:通过名字.属性访问

其中第(2)条,STRING类型可以隐式地转换为DOUBLE类型,要注意STRING类型的值要为“32.1”这种数字形式,如果是“aa.b”这种非数字类型就不能转换成DOUBLE类型。

第 4 章 DDL 数据定义

1.创建数据库

create database [if not exits] database2 [location '/db_hive2.db'];

注:【】内为可选选项,location ‘位置’:指定数据库存放位置 

hive>drop databases like ’db_hive2*’;

查询以db_hive2开头的数据库

Desc database db_hive2

查看db_hive2数据库详细信息

  1. 删除数据库

1)删除空数据库

hive>drop database db_hive2;

3)如果数据库不为空,可以采用 cascade 命令,强制删除

hive> drop database db_hive cascade;

2.创建表

 

如:create table test(id int,name string)

 row format delimited fields terminated by ‘,’;

创建一个包含id、name字段的test表,字段以“,”分割。

 

 总结:默认情况下创建的是管理表(内部表),当创建表时加了EXTERNAL关键字时,创建的是外部表。当删除表时,如果是管理表,则会将元数据和数据全部删除,也就是完全删除;如果是外部表,则只会删除元数据,不会删除数据,元数据就是表名,当重新创建一个相同的表名时,再次查看数据还是可以查看到的。

生产环境中更多地用的是外部表。

管理表与外部表的互相转换

修改内部表 student2 为外部表

alter table student2 set tblproperties('EXTERNAL'='TRUE');

修改外部表 student2 为内部表

alter table student2 set tblproperties('EXTERNAL'='FALSE');

查询表的类型

desc formatted student2;

注意:('EXTERNAL'='TRUE')('EXTERNAL'='FALSE')为固定写法,区分大小写!

第5章DML数据操作

5.1 数据导入

*5.1.1 向表中装载数据(Load) (常用)

1)语法

hive> load data [local] inpath '数据的 path' [overwrite] into table

student [partition (partcol1=val1,…)];

1load data:表示加载数据

2local:表示从本地加载数据到 hive 表;否则从 HDFS 加载数据到 hive

3inpath:表示加载数据的路径

4overwrite:表示覆盖表中已有数据,否则表示追加

5into table:表示加载到哪张表

6student:表示具体的表

7partition:表示上传到指定分区

如:

1)加载本地文件student.txthive student表中

hive (default)> load data local inpath

'/opt/module/hive/datas/student.txt' into table default.student;

2)加载 HDFS 文件到 hive student

hive (default)> load data inpath '/user/atguigu/hive/student.txt' into

table default.student;

3)加载数据并覆盖表中已有的数据

hive (default)> load data inpath '/user/atguigu/hive/student.txt'

overwrite into table default.student;

注意:从本地文件中上传student.txt到student表中是复制过去,但从HDFS文件中上传student.txt到student表中是剪切过去,也就是把student.txt文件剪切到student表中。

*5.1.2 通过查询语句向表中插入数据(Insert)(常用)

基本插入数据 (少用,因为一条条插入数据太慢了)

hive (default)> insert into table student_par

values(1,'wangwu'),(2,'zhaoliu');

 两种插入模式(常用,通过查询把数据导入)

  • 覆盖模式插入(insert overwrite)(根据单张表查询结果)

hive (default)> insert overwrite table student

select id, name from student where month='201709'; 

二、追加模式插入(insert into

hive (default)> insert into student

select id, name from student where month='201709'; 

insert into:以追加数据的方式插入到表或分区,原有数据不会删除

insert overwrite会覆盖表中已存在的数据

注意:insert 不支持插入部分字段

5.1.3查询语句中创建表并加载数据(As Select) (不常用)

根据查询结果创建表(查询的结果会添加到新创建的表中)

create table if not exists student3 as select id, name from student;

注意:查询的字段为创建新表的字段,并将查询出的数据作为新表的数据。

5.1.4 创建表时通过 Location 指定加载数据路径(不常用)

创建表,并指定在 hdfs 上的位置

hive (default)> create external table if not exists student5( id int, name string)

row format delimited fields terminated by '\t' location '/student;

注意:这种方式相当于创建一个表,然后指定了一个hdfs已有的路径,路径里面有数据,创建的表直接拥有此路径的数据。

5.1.5清除表中的数据(Truncate

注意:Truncate 只能删除管理表(内部表),不能删除外部表中数据

hive (default)> truncate table student;

6.2 分组(知识盲区,group by分组面试sql题中常考,需要好好掌握)

6.2.1 Group By 语句

GROUP BY 语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然

后对每个组执行聚合操作。

1)案例实操:

1)计算 emp 表每个部门的平均工资

hive (default)> select t.deptno, avg(t.sal) avg_sal from emp t group by

t.deptno;

2)计算 emp 每个部门中每个岗位的最高薪水

hive (default)> select t.deptno, t.job, max(t.sal) max_sal from emp t

group by

t.deptno, t.job;

6.2.2 Having 语句

1having where 不同点

1where 后面不能写分组函数,而 having 后面可以使用分组函数。

2having 只用于 group by 分组统计语句。

2)案例实操

1)求每个部门的平均薪水大于 2000 的部门

求每个部门的平均工资

hive (default)> select deptno, avg(sal) from emp group by deptno;

求每个部门的平均薪水大于 2000 的部门

hive (default)> select deptno, avg(sal) avg_sal from emp group by deptno

having avg_sal > 2000;

6.3 Join 语句

6.3.1 等值 Join

Hive 支持通常的 SQL JOIN 语句。

1)案例实操

1)根据员工表和部门表中的部门编号相等,查询员工编号、员工名称和部门名称;

hive (default)> select e.empno, e.ename, d.deptno, d.dname from emp e

join dept d on e.deptno = d.deptno;

6.3.2 表的别名

1)好处

1)使用别名可以简化查询。

2)使用表名前缀可以提高执行效率。

2)案例实操

合并员工表和部门表

hive (default)> select e.empno, e.ename, d.deptno from emp e join dept d

on e.deptno = d.deptno;

6.3.3 内连接

内连接:只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。

hive (default)> select e.empno, e.ename, d.deptno from emp e join dept d

on e.deptno = d.deptno;

6.3.4 左外连接

左外连接:JOIN 操作符左边表中符合 WHERE 子句的所有记录将会被返回。

hive (default)> select e.empno, e.ename, d.deptno from emp e left join

dept d on e.deptno = d.deptno;

6.3.5 右外连接

右外连接:JOIN 操作符右边表中符合 WHERE 子句的所有记录将会被返回。

hive (default)> select e.empno, e.ename, d.deptno from emp e right join

dept d on e.deptno = d.deptno;

6.3.6 满外连接

满外连接:将会返回所有表中符合 WHERE 语句条件的所有记录。如果任一表的指定字

段没有符合条件的值的话,那么就使用 NULL 值替代。

hive (default)> select e.empno, e.ename, d.deptno from emp e full join

dept d on e.deptno = d.deptno;

3)多表连接查询

hive (default)>SELECT e.ename, d.dname, l.loc_name

FROM emp e

JOIN dept d

ON d.deptno = e.deptno

JOIN location l

ON d.loc = l.loc;

大多数情况下,Hive 会对每对 JOIN 连接对象启动一个 MapReduce 任务。本例中会首先

启动一个 MapReduce job 对表 e 和表 d 进行连接操作,然后会再启动一个 MapReduce job 将第一个 MapReduce job 的输出和表 l;进行连接操作。

注意:为什么不是表 d 和表 l 先进行连接操作呢?这是因为 Hive 总是按照从左到右的

顺序执行的。

优化:当对 3 个或者更多表进行 join 连接时,如果每个 on 子句都使用相同的连接键的

话,那么只会产生一个 MapReduce job

第6章 查询(语法与MySQL一样)

注意:Hive没有索引,Hive查询的效率源于数据的分区分类。

4 By 区别:

(1)Order By:对数据进行全局排序,并且只有一个Reducer,不管我们对Reducer的数量如何设置,也只会有一个Reducer执行,因为全局排序只能在一个Reducer中执行。(注意:Order By进行全局排序,所以效率低,在公司生产环境中一般运行不了,因为数据太大,然而只有一个Reducer)

(2)Sort By:分区内有序,也就是每个Reducer内部进行排序,对全局结果集来说不是有序的。结果如下图类似:

 

(3)Distribute By:它的功能类似于MR中的Partition,对数据进行分区,一般结合Sort By一起使用。用法如下:(先将数据分区,再将各个分区内的数据进行排序)

(4)Cluster By:当 Distribute by 和 Sorts by 字段相同时,可以使用 Cluster by 方式。Cluster by 除了具有 Distribute by 的功能外还兼具 Sort by 的功能。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC。(一般用的比较少,因为很少有字段相同的情况)

7 章 分区表和分桶表

7.1 分区表

分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹,该文件夹下是该分区所

有的数据文件。Hive 中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过 WHERE 子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多,避免全表扫描。 (效率高的原因是因为查询直接在指定的分区表中进行,而不会进行全表扫描)

7.1.1 分区表基本操作

(1)创建分区表语法

hive (default)> create table dept_partition( deptno int, dname string, loc int)

partitioned by (day string)

row format delimited fields terminated by '\t';

注意:分区字段不能是表中已经存在的字段,可以将分区字段看作表的伪列。另外partitioned by注意partitioned,是ed结尾,后面很多地方partition没有ed结尾。

(2)加载数据到分区表中,把数据加载到表的指定分区中

hive (default)> load data local inpath

'/opt/module/hive/datas/dept_20200401.log' into table dept_partition

partition(day='20200401');

注意:分区表加载数据时,必须指定分区(不指定分区的话系统会自动生成一个分区名,此分区名对于日后的查询比较麻烦),一般在加载数据的时候指定好分区,分区命名一般以日期的形式,因为公司存储数据大都是按日期来存储。如:

(3)查询分区表中数据

单分区查询

hive (default)> select * from dept_partition where day='20200401';

多分区联合查询

hive (default)> select * from dept_partition where day='20200401'

union

select * from dept_partition where day='20200402'

union

select * from dept_partition where day='20200403';

hive (default)> select * from dept_partition where day='20200401' or

day='20200402' or day='20200403';

注意:在查询语句中,在where条件中可以像使用正常的字段一样使用分区字段,如day='20200401'一样,直接使用字段即可。

  1. 增加分区

语法:alter table 表名 add partition(分区名字);

创建单个分区

hive (default)> alter table dept_partition add partition(day='20200404');

同时创建多个分区

hive (default)> alter table dept_partition add partition(day='20200405')

partition(day='20200406');

注意:同时创建多个分区时,分区与分区之间用空格隔开。

(5)删除分区

删除单个分区

hive (default)> alter table dept_partition drop partition (day='20200406');

同时删除多个分区

hive (default)> alter table dept_partition drop partition(day='20200404'), partition(day='20200405');

注意:同时删除多个分区时,分区与分区之间用逗号‘,’隔开。

(6)查看分区表有多少分区

hive> show partitions dept_partition;

注意:这里partitions是以s结尾的。

(7)查看分区表结构

hive> desc formatted dept_partition;

总结partition:创建分区表时,partitioned以ed结尾;增删查时,partition不变,查看分区表时,partitions以s结尾。

7.1.2 二级分区

思考: 如果一天的日志数据量也很大,如何再将数据拆分?可以用二级分区,按天按小时进行分区,两层分区。

1.创建二级分区表

hive (default)> create table dept_partition2( deptno int, dname string, loc string) partitioned by (day string, hour string)  

row format delimited fields terminated by '\t';

注意:二级分区的创建,就是在partitioned分区里写两个字段,中间用逗号隔开。

2.正常的加载数据

1)加载数据到二级分区表中

hive (default)> load data local inpath

'/opt/module/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401', hour='12');

注意:加载数据要指定二级分区的位置,即传入两个分区字段的值。

2)查询分区数据

hive (default)> select * from dept_partition2 where day='20200401' and

hour='12';

注意:这里where条件后面,可以不给条件,也可以只给一个条件,也可以给两个条件,但条件与条件之间用and连接。

3.把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式

提示:这里的意思是,用hadoop命令将数据上传到分区目录下时,分区目录是用hadoop命令创建的,不是用HQL语句创建的分区,那么用Hive语句操作这个分区目录时,不会显示此目录的信息,因为不是用HQL创建的,那么如何让Hadoop命令创建的分区目录可以成为HQL语句的呢?接下来就是三种关联方式。

  1. 方式一:上传数据后修复

用hadoop命令创建分区目录并将数据放入分区中

hive (default)> dfs -mkdir -p

/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=13;

hive (default)> dfs -put /opt/module/datas/dept_20200401.log

/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=13;

查询数据(查询不到刚上传的数据,因为不是用HQL创建的分区)

hive (default)> select * from dept_partition2 where day='20200401' and

hour='13';

执行修复命令

hive> msck repair table dept_partition2;

再次查询数据 (执行了上面一条命令后分区目录会自动整理,Hadoop创建的分区目录有效)

hive (default)> select * from dept_partition2 where day='20200401' and

hour='13';

2)方式二:上传数据后添加分区

用hadoop命令创建分区目录并将数据放入分区中

hive (default)> dfs -mkdir -p

/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=14;

hive (default)> dfs -put /opt/module/hive/datas/dept_20200401.log

/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=14;

执行添加分区 (相当于添加一个分区,分区名和hadoop创建的分区目录一样,将hadoop创建的分区目录覆盖掉,使这个分区名有效)

hive (default)> alter table dept_partition2 add

partition(day='20200401',hour='14');

查询数据

hive (default)> select * from dept_partition2 where day='20200401' and

hour='14';

(3)方式三:创建文件夹后 load 数据到分区

提示:这种方式就是正常的load加载数据,和上面(2)的方式差不多,用相同的分区名覆盖掉hadoop创建的分区目录,然后使分区名有效

用hadoop命令创建分区目录

hive (default)> dfs -mkdir -p

/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=15;

用load data加载数据的方式上传数据

hive (default)> load data local inpath

'/opt/module/hive/datas/dept_20200401.log' into table

dept_partition2 partition(day='20200401',hour='15');

查询数据

hive (default)> select * from dept_partition2 where day='20200401' and

hour='15';

4.动态分区

一、(复杂方式,可以不用)

动态分区指的是系统自动进行分区,我们给定一个分区字段,系统会按照这个字段来进行智能分区,不需要我们指定分区。而静态分区指的是我们给定一个分区,把数据insert进去。

  1. 开启动态分区功能(默认 true,开启)

hive.exec.dynamic.partition=true

2)设置为非严格模式(动态分区的模式,默认 strict,表示必须指定至少一个分区为静态分区,nonstrict 模式表示允许所有的分区字段都可以使用动态分区。) 

注意:默认是严格模式,不能使用动态分区,用动态分区的时候要设置为非严格模式。

(3)案例实操

需求:将 dept 表中的数据按照地区(loc 字段),插入到目标表 dept_partition 的相应

分区中。

1)创建目标分区表

hive (default)> create table dept_partition_dy(id int, name string)

partitioned by (location int)

row format delimited fields terminated by '\t';

注意:分区字段不能和普通字段的名字相同。

2)设置动态分区 (先设置为非严格模式,再往分区表里插入数据)

hive (default)> set hive.exec.dynamic.partition.mode = nonstrict;

hive (default)> insert into table dept_partition_dy partition(location) select

deptno, dname, location from dept;

注意:partion()分区里只填分区字段名即可,不能给定参数(给定参数属于静态分区),然后在select语句中的字段里,最后一个字段要填写分区字段,与括号里的分区名相对于,这样就能告诉系统哪个是分区字段,这里分区字段即location

3)查看目标分区表的分区情况

hive (default)> show partitions dept_partition_dy;

说明:其实动态分区,就是给定一个分区字段,然后将另一个表的数据导入进来,但导入进来的数据会按照分区归类。

比如创建了一个dept_1的表,然后要将dept表中的数据导入到dept_1表中。dept_1表中有id int, name string两个字段以及分区字段location int,dept表中有deptno, dname, location三个字段,其中dept表的location字段在插入数据的时候放在最后,那么系统将会按照dept表中的location字段里的数据进行分区。dept_1和dept表中对应的location名字可以不一样。只要对应语法上的位置即可。

二、简单方式,3.0版本新特性(常用)

上面的方式一中,我们需要先指定为非严格模式,再将数据进行分区插入;而在3.0版本中,可以省略两个步骤。(1.不用开启非严格模式,系统自动转换。2.不需要指定分区字段,在select语句中最后一个字段为分区字段即可。)

如:

1)创建目标分区表

hive (default)> create table dept_partition_dy(id int, name string)

partitioned by (location int)

row format delimited fields terminated by '\t';

2)插入数据并且自动分区归类

hive (default)> insert into table dept_partition_dy

select deptno, dname, location from dept;

说明:和上面的语句对比一下,省略了partion(location)这句,以及不用指定非严格模式。

分桶表

分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理

的分区。对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围

划分。

分桶是将数据集分解成更容易管理的若干部分的另一个技术。

分区针对的是数据的存储路径;分桶针对的是数据文件。

分桶表就是将一个表分成多个小文件,一般用于数据量极大的时候。(了解即可,不重点掌握)

创建分桶表

create table stu_buck(id int, name string)

clustered by(id)

into 4 buckets

row format delimited fields terminated by '\t';

第 8 章 函数

8.1系统内置函数

1)查看系统自带的函数

hive> show functions;

2)显示自带的函数的用法

hive> desc function upper;

3)详细显示自带的函数的用法

hive> desc function extended upper;

 

注意:一、多指的是输入数据的行数,不是数据的个数,比如UDAF(聚合函数),多行数据聚合成一行数据;再比如UDTF:一行数据变成多行数据(wordcount案例就是这种)

8.2 常用内置函数

8.2.1 空字段赋值  NVL( valuedefault_value)

(1)函数说明

NVL:给值为 NULL 的数据赋值,它的格式是 NVL( valuedefault_value)。它的功能是如

value NULL,则 NVL 函数返回 default_value 的值,否则返回 value 的值,如果两个参数都为 NULL ,则返回 NULL

其中default_value可以为字段,也可以为确定的值。

(2)查询:如果员工的 comm NULL,则用-1 代替

hive (default)> select comm,nvl(comm, -1) from emp;

(3)查询:如果员工的 comm NULL,则用领导id列代替

hive (default)> select comm,nvl(comm, id) from emp;

8.2.2 CASE WHEN THEN ELSE END

按需求查询数据

sum(case sex when '' then 1 else 0 end) male_count这句表示:如果sex等于男返回1,否则返回0,然后将结果累加。

多条件写法:sum(case sex when a then 1 when b then 2...else 0 end)

多条件写法就是将when then 多次写即可。

上面语句效果等同于下面,if()函数也可以嵌套

8.2.3 行转列

(1)CONCAT(string A/col, string B/col)

返回输入字符串连接后的结果,支持任意个输入字符串或字段;如:

拼接字符:

结果显示:a-b-c

拼接字段:

 2CONCAT_WS(separator, str1, str2,...):

第一个参数为一个分隔符,后面都是字符串或字段。如:

结果显示:a-b-c

注意: CONCAT_WS must be "string or array<string>,参数必须为String或String数组

如:select concat_ws(|,collect_set(name));将数组进行处理。Name1|name2|name3|....

3collect_list( column ):

传入字段,将该列返回成一行数据(数组形式),并且不去除重复数据;如:

4collect_set( column ):

传入字段,将该列返回成一行数据,并且去除重复数据;如:

注意:(3)和(4)两个函数只接受基本数据类型,其他类型不支持!

列转行:

  1. EXPLODE(col)将一列中复杂的 Array 或者 Map 结构拆分成多行。

LATERAL VIEW (测斜表,用于把炸裂出的列与原表中的列相关联)

用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias

      LATERAL VIEW EXPLODE(col) 表别名 AS 被拆分的列的别名

说明:当需求只涉及拆分当前字段时,可以只用explode(column),如下方式;如果需求涉及到拆分当前字段后并关联原表字段信息,那就需要lateral View 关键字,不然字段行数匹配不上,如5.2示例。

如:

------> 

注意:explode()只支持array 或 map ,不支持其他类型,其他类型需要用

split(字段,分隔符)函数进行处理,将其转化为array类型;如:

(5.2)案例需求,将如下格式变为后面格式:

 ----->

 

建表语句:

8.3 窗口函数(开窗函数)

1)相关函数说明

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

说白了,就是像Lateral View一样,匹配行,不然的话数据不对称。有了OVER()函数可以更方便地进行数据的处理,如行与行之间数据的相加等操作。

也跟group by差不多,对数据集进行分组,但比group by更加灵活,可以指定分组以及排序,其实就是开窗口,不同的数据在不同的区域进行数据处理。

CURRENT ROW:当前行

n PRECEDING:往前 n 行数据

n FOLLOWING:往后 n 行数据

UNBOUNDED:起点,

UNBOUNDED PRECEDING 表示从前面的起点,

UNBOUNDED FOLLOWING 表示到后面的终点

LAG(col,n,default_val):往前第 n 行数据,default_val可填可不填,不填默认用null代替,也可以填个固定默认值,也可以填一个字段,表示用当前这行数据。(default_val用于补充没有匹配到数据的行。)

LEAD(col,n, default_val):往后第 n 行数据,default_val 和LAG函数中的一样。

NTILE(n)把有序窗口的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对

于每一行,NTILE 返回此行所属的组的编号。注意:n 必须为 int 类型。

即:把数据分成n等份,如有10条数据,n为5,则把数据等分为5份,每份2条数据。

说明:蓝色字体是用在OVER()函数里面的,用于控制分组的行数,并且不常用;

  红色字体是用在OVER()函数前面的,用于数据的处理,并且常用;

特别说明:上述的这些函数必须跟着over()一起使用,不能单独使用。

窗口函数一般跟聚合函数一起使用,进行数据的加减计算等,来完成需求:

聚合函数:count、sum、avg、max、min

2)数据准备:nameorderdatecost

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

3)创建 hive 表并导入数据

create table business(

name string,

orderdate string,

cost int

) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

load data local inpath "/opt/module/data/business.txt" into table

business;

  1. 按需求查询数据

(4.1)查询顾客及总人数

select

name,

count(*) over ()

from business;

结果显示:

说明:如果没有over()函数的话,那么查询出来的count(*)只有一行数据,name字段与count(*)字段匹配不上,所以会出错。而用了over()函数之后,count(*)字段的数据会与每一个name字段的数据相匹配,因为over()函数将整张表作为了一个窗口。

(4.2)查询在 2017 4 月份购买过的顾客及总人数

select

name,

count(*) over ()

from business

where substring(orderdate,1,7) = '2017-04'

group by name;

结果显示:

注明:这里用over(),over()中没有写其他功能,那它会将整个表作为一个整体计算并对应每行数据显示出来。

substring(字符串,起始位置,截取多少位):substring()函数用于截取字符串,字符串位置从0开始计算,注意第三个参数代表截取多少位,,而不是截取到字符串哪个位置,可以不填写表示截取到字符串最后一位。

(4.3)查询顾客的购买明细及月购买总额

select

name,

orderdate,

cost,

sum(cost) over(partition by name, month(orderdate))

from business;

结果显示:

说明:sum(cost) over(partition by name, month(orderdate)) 表示,按照相同人名、同一月份进行开窗,数据在各自的窗口进行处理,sum(cost)计算的是各个区内的数据,不是整个表的数据。也就是对相同人名、同一月份进行开窗。

(4.4)将每个顾客的 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;

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

(4.5)查看顾客上次的购买时间

select

name,

orderdate,

cost,

lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate )

as time1,

lag(orderdate,2) over (partition by name order by orderdate) as

time2

from business;

结果显示:

说明:lag(col,n,default_val)函数要用在over()前面。表示往前n行取数据,其中前面没有行的,则用default_val代替。LEAD(col,n,default_val)函数用法和LAG(col,n,default_val)函数一样,表示往后n行取数据。

(4.6)查询前 20%时间的订单信息

select name,

orderdate,

cost,

ntile(5) over(order by orderdate) sorted

from business;

结果显示:

说明:ntile(n)函数会将数据等分成n份。

select * from (

select name,

orderdate,

cost,

ntile(5) over(order by orderdate) sorted

from business ) t

where sorted = 1;

结果显示:

8.4 Rank(窗口函数)

1)函数说明:就是对数据进行排序,注意要跟over()一起用才行,并且Over()函数必须跟着分区或排序条件。

RANK() :排序相同时会重复,总数不会变,如:1-2-3-3-5-6

DENSE_RANK() 排序相同时会重复,总数会减少,如:1-2-3-3-4-5

ROW_NUMBER() 会根据顺序计算,如:1-2-3-4-5

例:结果显示的是rank()函数

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

Where rp < 4;

 

8.5自定义函数

1Hive 自带了一些函数,比如:max/min 等,但是数量有限,自己可以通过自定义 UDF

方便的扩展。

2Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDFuser-defined function)。

3根据用户自定义函数类别分为以下三种:

1UDFUser-Defined-Function

一进一出

2UDAFUser-Defined Aggregation Function

聚集函数,多进一出

类似于:count/max/min/sum/avg

3UDTFUser-Defined Table-Generating Functions

一进多出

lateral view explode()

4)编程步骤:

1)继承 Hive 提供的类

org.apache.hadoop.hive.ql.udf.generic.GenericUDF

org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;

2)实现类中的抽象方法

3)在 hive 的命令行窗口创建函数

添加 jar

add jar linux_jar_path

创建 function

create [temporary] function [dbname.]function_name AS class_name;

4)在 hive 的命令行窗口删除函数

drop [temporary] function [if exists] [dbname.]function_name;

注明:[temporary]为临时的意思,可写可不写,写了temporary则当窗口关闭之后函数失效,不写temporary则函数时永久性的关闭窗口也不会自动删除函数。

Function_name :函数名

Class_name :函数的全类名

(5)自定义函数的步骤:

(1)自定义 UDF:继承 GenericUDF,重写 evaluate 方法,然后打包加载到 hive 中,在 hive 中创建函数导入自定义 UDF 的全类名即可。

 (2)自定义 UDTF:继承 GenericUDTF,重写 3 个方法:initialize(自定义输出的列名和类型)、process(将结果返回 forward(数据集))、close,然后打包加载到 hive 中,在 hive 中创建函数导入自定义 UDTF 的全类名即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/411352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web 攻防之业务安全:Response状态值修改测试(修改验证码返回值 绕过限制.)

Web 攻防之业务安全&#xff1a;Response状态值修改测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台&#xff08;操作系统、数据库&#xff0c;中间件等&#xff09;、业务系统自身&#xff08;软件或设备&#xff09;、业务…

2.17、多生产者-多消费者进程

桌子上有一只盘子&#xff0c;每次只能向其中放入一个水果。爸爸专向盘子中放苹果&#xff0c;妈妈专向盘子中放橘子&#xff0c;儿子专等着吃盘子中的橘子&#xff0c;女儿专等着吃盘子中的苹果。只有盘子空时&#xff0c;爸爸或妈妈才可向盘子中放一个水果。仅当盘子中有自己…

Linux系统应用编程(四)Linux多线程

本篇文章主要内容&#xff1a;Linux系统应用编程&#xff08;四&#xff09;Linux多线程一、线程和进程的区别二、Linux多线程1.线程的使用 - 创建、退出、等待2.线程的同步 - 互斥量&#xff08;1&#xff09;互斥量的理解&#xff08;略&#xff09;&#xff08;2&#xff09…

你真的会自动化测试?自动化测试技术选型抉择

自动化测试框架 在学习自动化测试或者实践自动化测试时&#xff0c;我们一定会对一个名词不陌生&#xff0c;那就是“自动化测试框架”&#xff0c;而有些人也将Selenium、Appium这样的工具也称之为“自动化测试框架”&#xff0c;那么到底自动化测试框架如何理解呢&#xff1…

多种文字翻译软件-翻译常用软件

整篇文档翻译软件 整篇文档翻译软件是一种实现全文翻译的自动翻译工具&#xff0c;它能够快速、准确地将整篇文档的内容翻译成目标语言。与单词、句子翻译不同&#xff0c;整篇文档翻译软件不仅需要具备准确的语言识别和翻译技术&#xff0c;还需要考虑上下文语境和文档格式等多…

【Linux】一文带你探究网络世界的基石

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;计算机网络…

JVM专题

JVM类加载 Java里有如下几种类加载器&#xff1a; 引导类加载器&#xff1a;负责加载支撑JVM运行的位于JRE的lib目录下的核心类库&#xff0c;比如 rt.jar、charsets.jar等 扩展类加载器&#xff1a;负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包应用程序…

一篇文章让你搞懂TypeScript中的??和?:和?.和!.是什么意思

TypeScript中的??和?:和?.和!.是什么意思&#xff1f;知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现核心干货???:?.!.知识回调&#xff08;不懂就看这儿&#xff01;&#xff09; 知识专栏专栏链接TypeScript知识专栏https://blog.csdn.net/xsl_…

私有化部署GPT,告别网络困扰

最近的GPT是热火朝天&#xff0c;基本人手一个。工具用的好&#xff0c;工作5分钟&#xff0c;划水一整天。 不过最近Chat的访问越来越限制了&#xff0c;访问官网都有网络的问题&#xff0c;今天给大家介绍一个方案&#xff0c;私人独享属于自己的chat&#xff0c;不再担心想…

sdx12使能bluetooth

最后的效果&#xff1a; 1.驱动使能 apps_proc/kernel/msm-5.4/arch/arm/configs/vendor/sdxnightjar.config #add bt driver CONFIG_BTy CONFIG_MSM_BT_POWERy使用的芯片是sdx12 QCA6174A-1 管脚配置如下&#xff08;如果管脚不同&#xff0c;需要修改对应的dts&#xff09…

(十)排序算法-冒泡排序

1 排序算法 1.1 介绍 排序也称为排序算法&#xff08;Sort Algorithm&#xff09;&#xff0c;排序是将一组数据&#xff0c;依指定的顺序进行排列的过程。 1.2 排序的分类 &#xff08;1&#xff09;内部排序 指将需要处理的所有数据都加载到内部存储器中进行排序。 &…

C/C++程序设计——const关键字

1.修饰变量 1.1 作用 功能&#xff1a;不能直接被修改 const修饰变量&#xff0c;就相当于是定义了一个常量。该变量不能直接被修改&#xff0c;但是可以通过指针修改。 作用&#xff1a;便于维护、提前发现可能错误的修改 比如程序中大量使用了一个数字10&#xff0c;且不会…

GaussDB工作级开发者认证—第一章GaussDB数据库介绍

一. GaussDB概述 GaussDB是华为基于openGauss自研生态推出的企业级分布式关系型数据库。具备企业级复杂事物混合负载能力&#xff0c;同时支持分布式事务强一致性&#xff0c;同城跨AZ部署&#xff0c;数据0丢失&#xff0c;支持1000的计算节点扩展能力&#xff0c;4PB海量存储…

springcloud2.1.0整合seata1.5.2+nacos2.10(附源码)

springcloud2.1.0整合seata1.5.2nacos2.10&#xff08;附源码&#xff09; 1.创建springboot2.2.2springcloud2.1.0的maven父子工程如下&#xff0c;不过多描述&#xff1a; 搭建过程中也出现很多问题&#xff0c;主要包括&#xff1a; 1.seataServer.properties配置文件的组…

安全配置管理 (SCM):建立安全的基础

通过确保在端点中建立和维护理想的安全配置&#xff0c;让自己在安全的基础上做好准备&#xff0c;这样公司就不会因单个漏洞而分崩离析。安全配置管理涉及持续检测端点中各个组件之间的配置偏差和错误配置&#xff0c;并使它们重新对齐。 在本文中&#xff0c;将了解 Vulnera…

<Linux开发> linux应用开发-之-进程通信之管道例程

一、简介 所谓管道&#xff0c;是指用于连接一个读进程和一个写进程&#xff0c;以实现它们之间通信的共享文件&#xff0c;又称 pipe 文件。 向管道&#xff08;共享文件&#xff09;提供输入的发送进程&#xff08;即写进程&#xff09;&#xff0c;以字符流形式将大量的数…

Windows串口出厂测试工具与使用说明

WCHUsbSerTest是一款用于WCH USB转串口系列产品出厂测试的工具软件&#xff0c;方便用户对产品进行批量化功能测试。该软件支持以下特性&#xff1a; 支持设备热插拔检测&#xff0c;插入自动测试。支持两种测试模式&#xff1a;1个设备自测、2个设备互相连接测试。支持多种串…

VMware Horizon 8 2303 - 虚拟桌面基础架构 (VDI) 和应用软件

请访问原文链接&#xff1a;https://sysin.org/blog/vmware-horizon-8/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Version2303DocumentationRelease NotesRelease Date2023-03-30 虚拟桌面基础架构 (VDI) 和应用软件 VMw…

chagpt中文镜像版-ChatGPT工具下载

ChatGPT工具下载 ChatGPT是由OpenAI公司开发的预训练语言模型&#xff0c;目前已经开源并在GitHub上发布了相关代码和模型&#xff0c;提供了使用Python编写的API。如果您要使用ChatGPT&#xff0c;您可以通过以下步骤进行下载和安装&#xff1a; 在GitHub上下载&#xff1a;您…

【vue】 vue2 中使用 Tinymce 富文本编辑器

文章目录Tinymce 效果一、安装依赖二、封装组件-Tinymce.vue三、汉化文件-zh_CN.js四、vue使用组件封装五、整体目录结构六、可能会遇到的问题import "tinymce/icons/default" 路径找不到需要升级tinymce版本Tinymce 效果 一、安装依赖 npm i tinymce5.1.0 -S npm i…