大数据开发之Hive(查询、分区表和分桶表、函数)

news2024/11/19 10:24:40

第 6 章:查询

6.1 基本语法及执行顺序

1、查询语句语法

select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ORDER BY col_list]
[CLUSTER BY col_list| [DISTRIBUTE BY col_list] [SORT BY col_list]]
[LIMIT number]

2、书写次序和执行次序

顺序书写次序书写次序说明执行次序执行次序说明
1select查询from先执行表与表直接的关系
2from先执行表与表直接的关系on先执行表与表直接的关系
3join on先执行表与表直接的关系join先执行表与表直接的关系
4where先执行表与表直接的关系where过滤
5group by分组group by分组
6having分组后再过滤having分组后再过滤
7distribute by cluster by4个byselect查询
8sort by4个bydistinct去重
9order by4个bydistribute by cluster by4个by
10limit限制输出的行数sort by4个by
11union/union all合并order by4个by
12limit限制输出的行数
13union/union all合并

6.2 基本查询(Select…From)

6.2.1 全表和特定列查询

1、数据准备
分别创建部门和员工外部表,并向表中导入数据。
1)在/opt/module/hive/datas目录下编辑文件dept.txt,添加如下内容。

 vim dept.txt
10	行政部	1700
20	财务部	1800
30	教学部	1900
40	销售部	1700

2)在/opt/module/hive/datas目录下编辑文件emp.txt,添加如下内容。

vim emp.txt
7369	张三	研发	800.00	30
7499	李四	财务	1600.00	20
7521	王五	行政	1250.00	10
7566	赵六	销售	2975.00	40
7654	侯七	研发	1250.00	30
7698	马八	研发	2850.00	30
7782	金九	\N	2450.0	30
7788	银十	行政	3000.00	10
7839	小芳	销售	5000.00	40
7844	小明	销售	1500.00	40
7876	小李	行政	1100.00	10
7900	小元	讲师	950.00	30
7902	小海	行政	3000.00	10
7934	小红明	讲师	1300.00	30

3)上传数据到HDFS

dfs -mkdir /user/hive/warehouse/dept;
dfs -mkdir /user/hive/warehouse/emp;
dfs -put /opt/module/hive/datas/dept.txt /user/hive/warehouse/dept;
dfs -put /opt/module/hive/datas/emp.txt /user/hive/warehouse/emp;

4)建表语句,创建外部表
创建部门表dept

create external table if not exists dept(
deptno int,--部门编号
dname string, --部门名称
loc int --部门位置
)
row format delimited
fields terminated by '\t';

创建员工表

create external table if not exists emp(
empno int, --员工编号
ename string, --员工姓名
job string, --员工岗位(大数据工程师、前端工程师、java工程师)
sal double,--员工薪资
deptno int --部门编号
)
row format delimited fields terminated by '\t';

2、全表查询

select * from EMP;
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp ;

3、选定特定列查询

select empno, ename from emp;

注意:
1、SQL语言大小写不敏感
2、SQL可以写在一行或者多行
3、关键字不能被缩写也不能分行
4、各子句一般要分行写
5、使用缩进提高语句的可读性

6.2.2 列别名

紧跟列名,也可以在列名和别名之间加入关键字‘AS’
如:

select 
          ename AS name,
          deptno dn 
from emp;

6.2.3 常用函数(set hive.exec.mode.local.auto=true;本地模式)

1、求emp表的总行数(count)

select count(*) cnt from emp;

2、求emp表中工资的最大值

elect max(sal) max_sal from emp;

3、求emp表中工资的最小值

elect min(sal) min_sal from emp;

4、求emp表中工资的总和

elect sum(sal) sum_sal from emp;

5、求emp表中工资的平均值

select avg(sal) avg_sal from emp;

6.2.4 Limit语句

一般的查询会返回多行数据,在生产环境中,通常使用LIMIT子句用于限制返回的行数

select ename, sal from emp limit 5;
select ename, sal from emp limit 2,3;

6.2.5 Where语句

1、实例:查询出薪水大于1000的所有员工

select * from emp where sal > 1000;

6.2.6 比较运算符(Between/In/Is Null)

1、下面表中描述了谓词操作符,这些操作符同样可以用于JOIN…ON和HAVING语句中。

操作符支持的数据类型描述
A<=>B基本数据类型如果A和B都为NULL,则返回TRUE,如果以便为NULL,返回False
A RLIKE BSTRING类型B是基于java的正则表达式,如果A与其匹配,则返回TRUE;反之返回FALSE。匹配使用的是

2、案例实操
1)查询出薪水等于5000的所有员工

select * from emp where sal =5000;
OK
emp.empno       emp.ename       emp.job emp.mgr emp.hiredate    emp.sal emp.comm        emp.deptno
7839    KING    PRESIDENT       NULL    1981-11-17      5000.0  NULL    10

2)查询工资在500到1000的员工信息

select * from emp where sal between 800 and 1100;
OK
emp.empno       emp.ename       emp.job emp.mgr emp.hiredate    emp.sal emp.comm        emp.deptno
7369    SMITH   CLERK   7902    1980-12-17      800.0   NULL    20
7876    ADAMS   CLERK   7788    1987-5-23       1100.0  NULL    20
7900    JAMES   CLERK   7698    1981-12-3       950.0   NULL    30

3)查询job为空的所有员工信息

select * from emp where job is null;
OK
emp.empno       emp.ename       emp.job emp.mgr emp.hiredate    emp.sal emp.comm        emp.deptno
7369    SMITH   CLERK   7902    1980-12-17      800.0   NULL    20
7566    JONES   MANAGER 7839    1981-4-2        2975.0  NULL    20
7698    BLAKE   MANAGER 7839    1981-5-1        2850.0  NULL    30

4)查询工资是1500或5000的员工信息

select * from emp where sal IN (1500, 5000);
OK
emp.empno       emp.ename       emp.job emp.mgr emp.hiredate    emp.sal emp.comm        emp.deptno
7839    KING    PRESIDENT       NULL    1981-11-17      5000.0  NULL    10
7844    TURNER  SALESMAN        7698    1981-9-8        1500.0  0.0     30

6.2.8 Like 和 RLike

1、like关键字:使用LIKE运算选择类似的值
2、选择条件可以包含字符或数字:
1)% -> 代表零个或多个字符
2)_ -> 代表一个字符
3、RLIKE关键字:RLIKE子句是Hive中这个功能的一个扩展,其可以通过java的正则表达式这个更加强大的语言来指定匹配条件。
1)$x -> 代表以x结尾
2)^x -> 代表以x开头
3).* 任意数量字符
4). 一个任意字符
5)*上一个字符可以无限次出现或者不出现
4、实例操作
1)查找名字以“小”开头的员工信息

select * from emp where ename LIKE '小%';
select * from emp where ename RLIKE '^小';

2)查找名字以“明”结尾的员工信息

select * from emp where ename LIKE '%明';
select * from emp where ename RLIKE '明$';

3)查找名字中带有“明”的员工信息

select * from emp where ename  LIKE '%明%';
select * from emp where ename  RLIKE '[明]';

6.3 排序

6.3.1 每个Reduce内部排序(Sort By)

1、Sort by:在每个Reduce内部进行排序,对全局结果集来说不是有序。sort by为每个reducer产生一个排序文件,每个Reducer内部进行排序,对全局结果来说不是排序。
2、通过命令设置reduce个数

set mapreduce.job.reduces=3;

3、案例实操:
1)根据部门编号降序查看员工信息

select * from emp sort by deptno desc;

2)将查询结果导入到文件中

insert overwrite local directory '/opt/module/hive/datas/sortby-result'
row format delimited fields terminated by '\t '
select * 
from emp 
sort by deptno desc;

6.3.2 分区(Distribute By)

1、Distribute By
在有些情况下,我们需要控制某个特定行应该在哪个reducer,通常时为了进行后续的聚集操作。distribute by可以实现。distribute by类似MR中的partition(自定义分区),进行分区,结合sort by 使用。
2、案例分析
1)先按照部门编号分区,再按照员工薪水降序排序

set mapreduce.job.reduces=3;
insert overwrite local directory '/opt/module/hive/datas/distribute-result'
row format delimited fields terminated by '\t'
select
       ename,
       empno,
       deptno,
       sal 
from emp 
distribute by deptno
sort by sal desc;

注意:

  • distribute by的分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一起。
  • Hive要求DISTRIBUTE BY语句要写在SORT BY语句前面。

6.3.3 Cluster By

1、cluster by:
1)当distribute by和sort by字段相同时,可以使用cluster by方式。
2)cluster by除了具有distribute by的功能外还兼具sort by的功能。
2、案例:查询emp表中的员工信息,并按照部分编号分区排序。

select ename,empno,deptno,sal from emp cluster by deptno;
select ename,empno,deptno,sal from emp distribute by deptno sort by deptno;

第 7 章 分区表和分桶表

我们创建一个hive表时,此时在hdfs上就在默认路径上创建了一个以表名字命名的文件夹。Hive表中的数据在hdfs上则是对应文件夹下的所有文件。在查询表中数据时,其实就是将文件下的所有文件进行读取,在海量数据的场景下,这无疑是非常耗时的,并且在实际生产环境中,往往会进行查询过滤。
所以,如何在海量数据的场景下进行高效的查询过滤呢?

7.1 分区表

1、分区表实际上就是对应一个HDFS文件系统上的独立的文件夹。
2、该文件夹下是该分区所有的数据文件。
3、Hive中的分区就是分目录,把一个大的数据集根据业务需求分割成小的数据集。
4、在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。

7.1.1 分区表基本操作

1、需要根据日期对日志进行管理,通过部门信息模拟
2、创建分区表语法

create table dept_partition(
deptno int, --部门编号
dname string, --部门名称
loc string --部门位置
)
partitioned by (day string)
row format delimited fields terminated by '\t';

注意:分区字段不能是表中已经存在的数据,可以将分区字段看作表的伪列。
3、数据准备
为每个分区准备数据,我们根据日期对日志进行管理,通过部门信息模拟

vim dept_20200401.log
10	行政部	1700
20	财务部	1800 
vim dept_20200402.log
30	教学部	1900
40	销售部	1700
vim dept_20200403.log
50	运营部	2000
60	人事部	1900

4、案例:
1)向dept_partition表的分区加载数据

load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition partition(day='20200401'); 
load data local inpath '/opt/module/hive/datas/dept_20200402.log' into table dept_partition partition(day='20200402');
load data local inpath '/opt/module/hive/datas/dept_20200403.log' into table dept_partition partition(day='20200403');

注意:分区表加载数据时,必须指定分区
在这里插入图片描述
2)查询分区表中数据
单分区查询

select * from dept_partition where day='20200401';

多分区联合查询(union必走mr效率较低)

select * from dept_partition where day='20200401'
              union
              select * from dept_partition where day='20200402'
              union
              select * from dept_partition where day='20200403';
select * from dept_partition where day='20200401' or
                day='20200402' or day='20200403' ;			

5、增加分区
1)添加单个分区

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

2)同时添加多个分区

alter table dept_partition add partition(day='20200405') partition(day='20200406');

6、删除分区
1)删除单个分区

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

2)同时删除多个分区

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

7、查看分区表结构

desc formatted dept_partition;
# Partition Information          
# col_name              data_type               comment             
day                   string    

7.1.2 二级分区

思考:在根据日期分区后,如果一天的日志数据量也很大,如何再将数据拆分?
1、创建二级分区表

create table dept_partition2(
       deptno int,
       dname string,
       loc string
)
partitioned by (day string, hour string)
row format delimited fields terminated by '\t';

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

load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401', hour='11');

2)查找分区数据

select * from dept_partition2 where day='20200401' and hour='11';

3、让分区表和数据产生关联的三种方式
1)、方式一:上传数据后修复
(1)上传数据

 dfs -mkdir -p /user/hive/warehouse/dept_partition2/day=20200401/hour=12;
 dfs -put /opt/module/hive/datas/dept_20200402.log /user/hive/warehouse/dept_partition2/day=20200401/hour=12;

(2)查询数据(查询不到刚上传的数据)

select * from dept_partition2 where day='20200401' and hour='12';

(3)执行修复命令

msck repair table dept_partition2;

(4)再次查询数据

 select * from dept_partition2 where day='20200401' and hour='12';

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

dfs -mkdir -p /user/hive/warehouse/dept_partition2/day=20200401/hour=13;
dfs -put /opt/module/hive/datas/dept_20200403.log /user/hive/warehouse/dept_partition2/day=20200401/hour=13;

(2)执行添加分区

alter table dept_partition2 add partition(day='20200401',hour='13');

(3)查询数据

select * from dept_partition2 where day='20200401' and hour='14';

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

dfs -mkdir -p /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=14;

(2)上传数据

load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table
 dept_partition2 partition(day='20200401',hour='14');

(3)查询数据

select * from dept_partition2 where day='20200401' and hour='14';

7.1.3 动态分区

引言:关系型数据库中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中。Hive中也提供类似的操作,即动态分区(Dynamic Partition),只不过,使用Hive的动态分区,需要进行相应的配置。
1、开启动态分区参数设置
1)开启动态分区功能

set hive.exec.dynamic.partition=true;

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

set hive.exec.dynamic.partition.mode=nonstrict

3)在所有执行MR的节点上,最大一共可以创建多少个动态分区。默认1000

set hive.exec.max.dynamic.partitions=1000;

4)在每个执行MR的节点上,最大可以创建多少个动态分区
该参数需要根据实际的数据来设定。比如,源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认100,则会报错。

set hive.exec.max.dynamic.partitions.pernode=100;

5)整个MR Job中,最大可以创建多少个HDFS文件。默认100000

set hive.exec.max.created.files=100000;

6)当有空分区生成时,是否抛出异常。一般不需要设置。默认false

set hive.error.on.empty.partition=false;

2、案例
需求:将dept表中的数据按照地区(loc字段),插入到目标表dept_partition_loc的相应分区中
1)创建部门地区分区表

create table dept_partition_dynamic(
       id int,
       name string
)
partitioned by (loc int)
row format delimited fields terminated by '\t';

2)以动态分区的方式向表中插入数据

insert into table dept_partition_loc partition(loc) select deptno, dname, loc from dept;
FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict

set hive.exec.dynamic.partition.mode = nonstrict;

insert into table dept_partition_dynamic partition(loc) select deptno, dname, loc from dept;

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

show partitions dept_partition;
OK
partition
loc=1700
loc=1800
loc=1900

7.2 分桶表

1、分桶表
对于一张表或分区,Hive可以进一步组织成桶,也就是更为细粒度的数据范围划分。分区针对的是数据的存储路径(细分文件夹);分桶针对的是数据文件(按规则多文件放在一起)。
2、案例:创建分桶表
1)创建分桶表

create table stu_bucket(id int, name string)
clustered by(id) 
into 4 buckets
row format delimited fields terminated by '\t';

2)查看表结构

desc formatted stu_bucket;
Num Buckets:            4     

注意:想要将表创建为4个桶,需要将hive中mapreduce.jog.reduces参数设置为>=4或设置为-1
3)导入数据到分桶表中

load data local inpath   '/opt/module/hive/datas/student.txt' into table stu_bucket;

4)查看创建的分桶表中是否分为4个桶
在这里插入图片描述
5)查询分桶的数据

select * from stu_bucket;

6)分桶规则
Hive的分桶采取对分桶字段的值进行哈希,然后除以桶的个数求余
7)分桶表操作需要注意的事项:
(1)mapreduce.job.reduces=-1,让Job自行决定需要用多少个reduce或者将reduce的个数设置为大于等于分桶表的数量。
(2)从hdfs中load数据到分桶表中,避免本地文件找不到问题
8)insert方式将数据导入分桶表

truncate table stu_bucket;(删除表内数据,不删表结构,因此只能删内表)
insert into table stu_bucket select * from student ;

第 8 章:函数

8.1 系统内置函数

1)查看系统自带的函数

show functions;

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

desc function abs;

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

desc function extended abs;

8.2 常用内置函数

8.2.1 空字段赋值-NVL(防止空字段参与计算)

1、函数说明

desc function extended nvl;

2、解释

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

3、案例
1、数据准备
采用员工表
2、查询
1)如果员工的comm为NULL,则用0代替

select ename,comm,nvl(comm, 0) comm_0 from emp;

2)如果员工的job为NULL,则用领导id代替

select ename, mgr,comm, nvl(job,mgr) comm_mgr from emp;

8.2.2 CASE WHEN ELSE END

1、案例
1)数据准备,在/opt/module/hive/datas目录下创建emp_sex.txt,添加如下内容

vim emp_sex.txt
悟空,A,男
大海,A,男
宋宋,B,男
凤姐,A,女
婷姐,B,女
婷婷,B,

2)创建emp_sex表并导入数据

create table emp_sex(
name string, 
dept_id string, 
sex string
) 
row format delimited fields terminated by ",";

load data local inpath '/opt/module/hive/datas/emp_sex.txt' into table emp_sex;

3)需求:求出不同部门男女各多少人。结果如下

select 
  dept_id,
  sum(case sex when '男' then 1 else 0 end) man_num,
  sum(case sex when '女' then 1 else 0 end) woman_num
from 
  emp_sex
group by  dept_id;

8.2.3 行转列

在这里插入图片描述
1、相关函数说明
1)CONCAT(string A/col,string B/col…)

select concat('abc','def') from src limit 1;
'abcdef'

2)CONCAT_WS(separator,str1,str2,…)

select concat_ws('.','www',array('facebook','com')) from src limit 1;
'www.facebook.com'

3)COLLECT_SET(col):去重汇总
4)COLLECT_LIST(col):汇总
2、案例
1)需求:把星座和血型一样的人归类到一起。结果如下:

射手座,A            大海|凤姐
白羊座,A            孙悟空|猪八戒
白羊座,B            宋宋|苍老师

2)数据准备

vim person_info.txt
孙悟空,白羊座,A
大海,射手座,A
宋宋,白羊座,B
猪八戒,白羊座,A
凤姐,射手座,A
苍老师,白羊座,B

3)操作

create table person_info(
name string, 
constellation string, 
blood_type string
) 
row format delimited fields terminated by ",";

load data local inpath "/opt/module/hive/datas/person_info.txt" into table person_info;

按需求查询结果

SELECT
t1.c_b,
CONCAT_WS("|",collect_set(t1.name))
FROM (
SELECT
NAME ,
CONCAT_WS(',',constellation,blood_type) c_b
FROM person_info
)t1 
GROUP BY t1.c_b

8.2.4 列转行

在这里插入图片描述
1、函数说明
1)EXPLODE(col):将hive表的一列中复杂的array或者map结构拆分成多行
2)SPLIT(string str,string regex):按照reget字符串分割str,会返回分割后的字符串数组

 SELECT split('oneAtwoBthreeC', '[ABC]') FROM src LIMIT 1;
  ["one", "two", "three"]

3)LATERAL VIEW:对拆分后的数据进行聚合
2、案例
1)需求

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

2)原始数据

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

3)操作

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

create table movie_info(
    movie string, 
    category string) 
row format delimited
fields terminated by "\t";

load data local inpath "/opt/module/hive/datas/movie_info.txt" into table movie_info;

4)按需求查询数据

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

8.2.5 窗口函数(开窗函数)

1、介绍
输入多行数据(一个窗口),为每行数据进行一次计算,返回一个值。灵活运用窗口函数可以解决如去重,排序等。
在这里插入图片描述
2、语法

Function (arg1 ...) over ([patition by arg1 ...] [order by arg1 ...] [<window_expression>])
FunctionOver()window_expression
支持的函数指定分析函数工作的数据窗口大小,窗口会随着行的变化而变化窗口边界的设置
聚合函数:sum()、max()等partition by:表示将数据先按字段进行分区n preceding : 向前n行 n following:向后n行 current row:当前行
排序函数:rank()、row_number()等Order by:表示将各个分区内的数据按字段进行排序unbounded preceding:从前面的起点开始 unbounded following:到后面的终点结束
统计比较函数:lead()、lag()等

3、数据准备
1)在/opt/module/hive/datas目录下创建business.txt,添加如下内容

vim business.txt
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

2)创建hive表并导入数据

create table business(
name string, 
orderdate string,
cost int
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';

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

4、实例
1)需求:查询在2017年4月份购买过的顾客,及总人数
(1)样例

name    consume_num
mart    2
jack    2
select 
name, 
count(name) over() 
from business 
where subString(orderdate,1,7) = '2017-04'
group by name;

2)需求:查询顾客的购买明细及月购买总额
(1)样例

name    orderdate       cost    month_sum
jack    2017-01-05      46      111
jack    2017-01-08      55      111
jack    2017-01-01      10      111
jack    2017-02-03      23      23
jack    2017-04-06      42      42

(2)分析
查询顾客的购买明细,即表中的所有的列,分别以name和orderdate分组,显然group by无法满足我们。这里我们用到over(partition by arg1)指定窗口函数的分区字段,在分区基础上进行窗口分析。
(3)案例

select 
name,
orderdate,
cost,
sum(cost) over(partition by name,month(orderdate)) 
from business;
OK
name    orderdate       cost    sum_window_0	
jack    2017-01-05      46      111
jack    2017-01-08      55      111
jack    2017-01-01      10      111
jack    2017-02-03      23      23
jack    2017-04-06      42      42
mart    2017-04-13      94      299
mart    2017-04-11      75      299
mart    2017-04-09      68      299
mart    2017-04-08      62      299
neil    2017-05-10      12      12
neil    2017-06-12      80      80
tony    2017-01-04      29      94
tony    2017-01-02      15      94
tony    2017-01-07      50      94

3)需求:将每个顾客的cost按照日期进行累加
计算表business的消费总额

select 
name,
orderdate,
cost, 
sum(cost) over() sample1 
from business;

在这里插入图片描述
计算每个人的销售总额
select
name,
orderdate,
cost,
sum(cost) over(partition by name) as sample2
from business;在这里插入图片描述
计算每个人截至到当天的消费总额

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

在这里插入图片描述
计算每个人截至到今天的消费总额(另一种写法)

select 
name,
orderdate,
cost, 
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4
from business;

计算每个人连续两天的消费总额

select 
name,
orderdate,
cost, 
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row ) as sample5
from business;

在这里插入图片描述
计算每个人从当前天到最后一天的消费总额

select 
name,
orderdate,
cost,
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample6 from business;.

在这里插入图片描述
rows必须跟在Order by子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数量行数量。
4)需求:查看顾客上次的购买时间
(1)样例

name    orderdate       cost    last_time
jack    2017-01-01      10      (…………………)
jack    2017-01-05      46      2017-01-01
jack    2017-01-08      55      2017-01-05

(2)函数介绍

LAG (scalar_expression[,offset] [,default]) OVER ([query_partition_clause] order_by_clause);

解释:
Lag函数用于统计窗口内往上第n行值,参数scalar_pexpression为列名,参数offset为往上几行,参数default是设置的默认值(当往上第n行为NULL时,取默认值,否则就为NULL)
(3)案例代码

select
name,
orderdate,
cost,
lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as last_time
from business;
OK
name    orderdate       cost    last_time
jack    2017-01-01      10      1900-01-01
jack    2017-01-05      46      2017-01-01
jack    2017-01-08      55      2017-01-05
jack    2017-02-03      23      2017-01-08
jack    2017-04-06      42      2017-02-03
mart    2017-04-08      62      1900-01-01

5)需求:查询前20%时间的订单信息
(1)分析
当前表中总共有14行数据,前20%,就是大约前三行,你会觉得很简单,将数据orderdate字段排序取前三即可,但是表中数据量持续变化,前20%的数据是变化的,这里需要使用ntile函数。
(2)函数介绍
Ntile函数,为已排序的行,均分为指定数量的组,组号按顺序排列,返回组号,不支持rows between
(3)案例

select
t1.name,
t1.orderdate,
t1.cost
from (
select
name,
orderdate,
cost,
ntile(5) over(order by orderdate) sorted from business
) t1
where t1.sorted = 1;
OK
t.name  t.orderdate     t.cost
jack    2017-01-01      10
tony    2017-01-02      15
tony    2017-01-04      29

8.2.6 Rank

1、函数说明
1)RANK():排序相同时会重复,总数不会变。重复的名次一样但是下一名名次会以前面人数+1来定
2)DENSE_RANK():排序相同时会重复,总数会减少。就是若有重复则最后一名的名词不会和总数相等 即并列
3)ROW_NUMBER():会根据顺序计算,字段相同就按排头字段继续排
2、数据准备
1)数据

vim score.txt
孙悟空	语文	87
孙悟空	数学	95
孙悟空	英语	68
大海	语文	94
大海	数学	56
大海	英语	84
宋宋	语文	64
宋宋	数学	86
宋宋	英语	84
婷婷	语文	65
婷婷	数学	85
婷婷	英语	78

2)导入数据

create table score(
name string,
subject string, 
score int) 
row format delimited
fields terminated by "\t";

load data local inpath '/opt/module/hive/datas/score.txt' into table score;

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

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;
OK
name    subject score   rp      drp     rmp
孙悟空  数学    95      1       1       1
宋宋    数学    86      2       2       2
婷婷    数学    85      3       3       3
大海    数学    56      4       4       4
宋宋    英语    84      1       1       1
大海    英语    84      1       1       2
婷婷    英语    78      3       2       3
孙悟空  英语    68      4       3       4
大海    语文    94      1       1       1
孙悟空  语文    87      2       2       2
婷婷    语文    65      3       3       3
宋宋    语文    64      4       4       4

8.3 自定义函数

1、内置函数:比如max/min等
2、根据用户自定义函数类别分为以下三种:
1)UDF:一进一出
2)UDAF:聚合函数,多进一出,类似:count/max/min
3)UDTF:炸裂函数,一进多出,类似:explode()
3、编程步骤
1)继承Hive提供的类
2)实现类中的抽象方法
3)在hive的命令行窗口创建函数
4、hive中引入自定义函数步骤
1)添加jar

add jar linux_jar_path

2)创建function

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

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

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

8.4 自定义UDF函数

1、需求:自定义一个UDF实现计算给定字符串的长度,例如:

select my_len("abcd");
ok
4

2、案例
1)创建Maven工程Hive
2)在工程项目的pom.xml文件中导入依赖
hive-exec
3)创建一个类

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;

/**
 * 自定义UDF函数,需要继承GenericUDF类
 * 需求: 计算指定字符串的长度
 */
public class MyStringLength extends GenericUDF {
    /**
     *
     * @param arguments 输入参数类型的鉴别器对象
     * @return 返回值类型的鉴别器对象
     * @throws UDFArgumentException
     */
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        // 判断输入参数的个数
        if(arguments.length !=1){
            throw new UDFArgumentLengthException("Input Args Length Error!!!");
        }
        // 判断输入参数的类型
        if(!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)){
            throw new UDFArgumentTypeException(0,"Input Args Type Error!!!");
        }
        //函数本身返回值为int,需要返回int类型的鉴别器对象
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    /**
     * 函数的逻辑处理
     * @param arguments 输入的参数
     * @return 返回值
     * @throws HiveException
     */
    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
       if(arguments[0].get() == null){
           return 0 ;
       }
       return arguments[0].get().toString().length();
    }

    @Override
    public String getDisplayString(String[] children) {
        return "";
    }
}

4)打包jar包上传到服务器/opt/module/hive/datas/myudf.jar
5)将jar包添加到hive的classpath

add jar /opt/module/hive/datas/myudf.jar;

8.5 创建临时函数

1、创建临时函数与开发好的java class关联

create temporary function my_len as "com.atguigu.hive. MyStringLength";

2、在hql中使用自定义的函数

select ename,my_len(ename) ename_len from emp;
OK
ename   _c1
fanfan  6
SMITH   5
ALLEN   5
WARD    4
JONES   5
MARTIN  6
BLAKE   5
CLARK   5
SCOTT   5
KING    4
TURNER  6
ADAMS   5
JAMES   5
FORD    4
MILLER  6

注意:临时函数只跟会话有关系,跟库没有关系,只有创建临时函数的会话不断,在当前会话下,任意一个库都可以使用,其他会话全部不能使用。

8.6 创建永久函数

注意:因为add jar 的方式本身也是临时生效,所以在创建永久函数的时候,需要执行路径

create function my_len2 
as "com.atguigu.hive.udf.MyUDF" 
using jar "hdfs://hadoop102:8020/udf/myudf.jar";

即可在hql中使用自定义的永久函数

select 
    ename,
    my_len2(ename) ename_len 
from emp;

删除永久函数

drop function my_len2;

注意:永久函数跟会话没有关系,创建函数的会话断了以后,其他会话也可以使用。

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

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

相关文章

RK3568驱动指南|驱动基础进阶篇-进阶2 让驱动快一点被加载实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

【每日一题】删除排序链表中的重复元素 II

文章目录 Tag题目来源解题思路方法一&#xff1a;遍历链表 写在最后 Tag 【遍历链表】【链表】【2024-01-15】 题目来源 82. 删除排序链表中的重复元素 II 解题思路 几乎所有链表的题目都可以先将链表转成数组&#xff0c;再对数组执行操作&#xff0c;最后将数组还原回链表…

手写Springboot核心流程

目录 Springboot启动流程 核心代码 验证效果 Springboot启动流程 创建Spring容器, 扫描并启动容器选择Tomcat/Jetty创建DispatchServlet, 与spring容器绑定将DispatchServlet添加到Tomcat启动Tomcat 核心代码 1. 首先, 创建两个module 2. maven依赖 springboot模块依赖 &l…

网络安全|GitHub 已成为恶意软件传播的严重污染源

Recorded Future 凸显了全球合法平台威胁的上升。 根据 Recorded Future最近 的一份报告&#xff0c;开发者平台GitHub最近已成为黑客用来托管和传播恶意软件的流行工具。 该平台为攻击者提供了将其行为伪装成合法网络流量的能力&#xff0c;这使得跟踪和确定攻击者的身份变得…

【漏洞复现】Sentinel Dashboard默认弱口令漏洞

Nx01 产品简介 Sentinel Dashboard是一个轻量级的开源控制台&#xff0c;提供机器发现以及健康情况管理、监控、规则管理和推送的功能。它还提供了详细的被保护资源的实际访问统计情况&#xff0c;以及为不同服务配置的限流规则。 Nx02 漏洞描述 Sentinel Dashboard存在默认弱…

当前页面一键回关

CSDN博客关注页面当前页面一键回关所有fans代码 f12打开控制台&#xff0c;输入以下代码 // 获取所有的button元素&#xff0c;根据它们的属性进行筛选 var buttons document.querySelectorAll("button[data-v-0947769e][data-ref^li_][data-id][classattention-btn]&qu…

11.云原生分布式数据库之TIDB

云原生专栏大纲 文章目录 为什么使用TIDB后端视角运维视角基础架构视角 TiDB Operator 简介软件版本要求部署tidbTIDB工具helm常用命令TIDB学习推荐资料 为什么使用TIDB 从后端视角、运维视角和基础架构视角来看&#xff0c;使用 TiDB 作为数据库系统可以获得分布式架构、高可…

肯尼斯·里科《C和指针》第6章 指针(3)

肯尼斯里科《C和指针》第6章 指针&#xff08;1&#xff09;-CSDN博客 肯尼斯里科《C和指针》第6章 指针&#xff08;2&#xff09;-CSDN博客 前置知识&#xff1a;左值右值 为了理解有些操作符存在的限制&#xff0c;必须理解左值(L-value)和右值(R-value)之间的区别。这两个…

LLM之LangChain(二)| LangChain中的Agent

在本文中&#xff0c;我们将讨论LangChain中的Agent及其各种类型。但在深入研究Agent之前&#xff0c;让我们先了解一下什么是LangChain和Agent。 一、什么是LangChain&#xff1f; LangChain是一种功能强大的自动化工具&#xff0c;可用于各种任务&#xff0c;它提供了可用于…

卸载Notepad++!事实已证明,它更牛逼……

本文系统全面的介绍了 Sublime Text&#xff0c;旨在成为最优秀的 Sublime Text 中文教程。 前言 Sublime Text 是一款跨平台代码编辑器&#xff08;Code Editor&#xff09;&#xff0c;从最初的 Sublime Text 1.0&#xff0c;到现在的 Sublime Text 3.0&#xff0c;Sublime …

突破界限:首个国产DeepSeek MoE的高效表现

前言 在人工智能技术的快速发展过程中&#xff0c;国产首个开源MoE&#xff08;Mixture of Experts&#xff09;大模型——DeepSeek MoE的推出&#xff0c;不仅标志着中国在全球AI领域的重大突破&#xff0c;而且在计算效率和模型性能上展现了显著的优势。这款160亿参数的模型…

医疗器械生物学评价系列标准

医疗器械生物学评价系列标准(GB/T 16886/ISO 10993)是保障医疗器械安全的基础标准&#xff0c;内容涵盖医疗器械生物学评价基本指导原则、各项生物学试验方法、样品制备方法、理化表征方法等&#xff0c;是医疗器械生物学试验、评价、技术审批的重要依据&#xff0c;是医疗器械…

计算机图形学作业:Cohen-Sutherland和Liang-Barsky 裁剪算法

参考书籍和资料&#xff1a; Liang-Barsky参考下面视频14.2.1 [14.2.1]--讲解经典的梁友栋-巴斯基算法。_哔哩哔哩_bilibili Cohen-Sutherland参考孔令德的计算机图形学实验及课程设计&#xff08;第二版&#xff09;&#xff0c;实验五直线段的裁剪 题目如下&#xff1a; …

R语言【文章复现】——集成式地绘制高分辨率的多样性分布图,对方法的检验和优化,以及处理思路的思考

参考文献 本文对一篇 2022 年发表在 New Phytologist 的绘图方法文章中的技术路线进行复现。 An integrated high-resolution mapping shows congruent biodiversity patterns of Fagales and Pinales Summary 文中,作者针对在全球尺度上绘制物种分布图提出了一种全新的方法…

大白菜U盘安装系统-戴尔电脑

1. 把U盘插入电脑&#xff0c;启动盘去大白菜官网找&#xff0c;镜像可以去微软官网下&#xff0c;想要专业版的网上找资源。 2. 重启电脑&#xff0c;等出现log之后狂按F12&#xff0c;进入BOSS模式。 3. 选择UEFI...也就是下面白色的&#xff0c;按下回车。 4. 选第一个 5.…

数据结构_C++语言描述_高教出版社

contents 前言一、绪论1.1 数据分析结构存储算法计算1.1.1 逻辑结构1.1.2 存储结构1.1.3 算法实现 1.2 数据类型1.3 算法方法 二、线性表2.1 线性表的逻辑结构2.2 线性表的存储结构2.2.1 顺序存储结构2.2.2 链式存储结构 2.3 线性表的操作算法2.3.1 顺序表的操作算法2.3.2 链表…

RK3568驱动指南|驱动基础进阶篇-进阶3 驱动代码使用Makefile的宏

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

Nvidia Jetson AGX Orin使用CAN与底盘通信(ROS C++ 驱动)

文章目录 一、Nvidia Jetson AGX Orin使用CAN通信1.1 CAN使能配置修改GPIO口功能1.2 can收发测试 二、通过CAN协议编写CAN的SocketCan ROS1驱动程序2.1 通讯协议2.2 接收数据节点2.3 发送数据节点2.4 功能包配置 三、ROS2驱动程序 一、Nvidia Jetson AGX Orin使用CAN通信 参考…

linux手动安装 vscode-server

适用场景 很多时候&#xff0c;我们需要在本机&#xff08;比如windows&#xff09;通过remote ssh访问远程服务器&#xff08;一般是ubuntu&#xff09;&#xff0c;但经常出现 vscode 一直连不上远程服务器的情况&#xff0c;看一下 log&#xff1a; 这个log表示远程服务器…

【2023年收入最高的10种编程语言】

在过去的一年时间里&#xff08;2022 年 10 月 1 日到 2023 年 10 月 1 日&#xff09; &#xff0c;DevJobsScanner 分析了来自世界各地的超过 1000 万份开发工作机会&#xff0c;以了解市场以及最热门、薪酬最高的编程语言。值得注意的是&#xff0c;本项研究只关注了来自美国…