Hive(五)DML数据操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive(五)DML数据操作相关的知识,希望对你有一定的参考价值。

参考技术A

语法

(1)load data:表示加载数据
(2)local:表示从本地加载数据到hive表;否则从HDFS加载数据到hive表
(3)inpath:表示加载数据的路径
(4)overwrite:表示覆盖表中已有数据,否则表示追加
(5)into table:表示加载到哪张表
(6)student:表示具体的表
(7)partition:表示上传到指定分区
案例

 2)导入本地数据

 3)查看person表数据

 2)清空 person表数据; truncate table person;

 3)查看person表清空情况(已经没有数据了)

 4)导入 HDFS 数据到 person表中

 5)重新查询 person表,查看数据情况

 2) 导入HDFS,无需添加 local

 3) row format delimited fields terminated by \'\\t\' ;

语法:insert into <table> <表名> <查询语句>
案例:
创建一张新表:create table if not exists person2(id int,name string,phone string);

将 person 表中id 为 1和3的数据插入到 person2表中。

查询person2表数据

方式二:into overwrite
语法:insert overwrite table <表名> <查询语句>
测试之前重新准备一张表

向 person6 表中添加数据。

数据结果

注意:使用 insert overwrite 后面必须加上 table ,否则报错
注意

语法 :create table [if not exists] <表名> as <查询语句>
描述 :根据查询结果创建表(查询的结果会添加到新创建的表中)
案例
按照person表的结果创建person3表

查询 person3

注意:使用查询结果创建数据表时,需要加入 关键字

管理表
语法 :create table [if not exists] <表名>(字段信息) row format delimited fields terminated by <分割符>location <加载数据路径>
案例 :加载person 表的数据。
查询 person 数据加载的地址

创建 person4 表并设置 person表的数据路径。

查询 person4 表信息;person4中的表数据全部来自于person表。

外部表

创建一个管理表 t1

向管理表t1中添加一条数据

创建t2 并指定t1数据的加载地址

查询 t2 表

删除 t1 表

再次查询 t2 表

验证 t1 为外部表时,删除t1表时,是否会删除数据。
重新创建 t1表

向t1中添加数据3

创建 t2(原来的给删除了)并指定为外部表,并加载 t1的数据路径

查询 t1 表结构(验证是否为外部表

查询 t2 数据(有数据2)

删除t1 表

查询 t2 表(数据并没有删除)

更加深刻理解 管理表和外部表之间的区别。

语法 :import table <全新的表名> from \'<Export 导出的地址>\';

查询 person_import 表

查看家目录,生成了 一个 aaa目录,目录中有一个 000000_0 文件

查看 000000_0文件;正好是 person表中的数据。

注意:这里的 overwrite 并不是可选项(可加不可加),这里必须加上overwrite ,否则会报错。

查看 000000_0文件;使用了制表符,对数据进行格式化。

查看 /aaa/000000_0 文件

查看person_bak 文件

语法 :hive -e "<sql语句>" > <输出路径>
案例

查看家目录中的 person_bak

语法 :export table <表名> to \'<HDFS地址>\'
案例 :将 person 表的数据导出到 HDFS /person2中

查看 /person2 的层次结构

查看 /person2/data/person

Hive学习——DDL&DML&DQL语句

目录

一、Hive数据类型

(一)Hive基本数据类型

(二)Hive的基本数据类型转换

(三)Hive集合数据类型

(四)文本文件数据编码

(五)读时模式

(六)Hive数据结构

二、DDL&DML命令

(一)数据库操作

1.创建数据库

2.查看数据库

3.修改数据库

4.删除数据库

5.切换(使用)指定数据库

(二)表操作

1.建表语法

2.内部表

3.外部表

4.内部表与外部表的转换

5.分区表

6.分桶表

7.高级建表语句

8.修改表与删除表

(三)数据操作

1.数据导入

2.插入数据

3.数据导出

三、DQL命令

1.DQL语法

2.字段名重命名——中文别名要用反引号,且as可有可无

3.join on——Hive仅支持等值连接

4.排序

5.UNION

四、Hive函数

1.查看所有的函数

2.日期函数

3.数学函数

4.流程控制函数

5.高级聚合函数


一、Hive数据类型

(一)Hive基本数据类型

类型

示例

类型

示例

TINYINT

10

SMALLINT

10

INT

10

BIGINT

100L

FLOAT

1.342

DOUBLE

1.234

DECIMAL

3.14

BINARY

1010

BOOLEAN

TRUE

STRING

'Book' or "Book"

CHAR

'YES' or "YES"

VARCHAR

'Book' or "Book"

DATE

'2013-01-31'

TIMESTAMP

'2020-01-31 00:13:00.345'

(二)Hive的基本数据类型转换

参考下图,可以从下至上进行转换

任何整数类型都可以隐式转换为一个范围更广的类型。tinyint=>int;int=>bigint;

所有整数类型、float、string(都是数字)都可以隐式转换为Double;

tinyint、smallint、int=>float;

boolean不能转换;

select '1.0'+2; -- 3
select '88' > 888;
select '1'+true;-- 报错,boolean不能转换
select cast('111' as int);-- 111

(三)Hive集合数据类型

(四)文本文件数据编码

vi 中输入特殊字符:
  • (Ctrl + v) + (Ctrl + a) => ^A
  • (Ctrl + v) + (Ctrl + b) => ^B
  • (Ctrl + v) + (Ctrl + c) => ^C
^A / ^B / ^C 都是特殊的控制字符,使用 more cat 命令是看不见的;可以使用cat - A file.dat 

1.创建一个表

create table s1(
    id int,
    name string,
    age int,
    hobby array<string>,
    score map<string,int>
);

2.XShell端创建文本文件

[root@lxm147 stufile]# cat -A /opt/stufile/s1.txt 
666^Alisi^A18^Aread^Bgame^Ajava^C97^Bhadoop^C87$

 3.上传数据

load data local inpath '/opt/stufile/s1.txt' into table s1;

select * from s1;

4.运行结果

(五)读时模式

        在传统数据库中,在加载时发现数据不符合表的定义,则拒绝加载数据。数据在写入 数据库时对照表模式进行检查,这种模式称为 " 写时模式 " schema on write )。 写时模式 -> 写数据检查 -> RDBMS         Hive中数据加载过程采用 " 读时模式 " (schema on read) ,加载数据时不进行数据格式的校验,读取数据时如果不合法则显示 NULL 。这种模式的优点是加载数据迅速。 读时模式 -> 读时检查数据 -> Hive ;好处:加载数据快;问题:数据显示 NULL

(六)Hive数据结构

二、DDL&DML命令

(一)数据库操作

  • Hive的默认数据库为default,如果不指定数据库,则默认使用default;
  • Hive的数据库名、表名不区分大小写;
  • 名字不能使用数字开头;
  • 不能使用关键字,尽量不使用特殊符号。

1.创建数据库

(1)语法

CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];-- K-V键值对信息

(2)案例

1)创建一个数据库,不指定路径:

create database db_hive1;

注:若不指定路径,其默认路径为$/opt/soft/hive312/warehouse/database_name.db

参考博文《Hive学习——单机版Hive的安装》2.2

2)创建一个数据库,指定路径:

create database db_hive2 location '/db_hive2';

create database abc location '/data/abc';

3)创建一个数据库带有dbproperties

create database db_hive3 with dbproperties('create_date'='2023-01-01');

2.查看数据库

(1)展示所有数据库

SHOW DATABASES [LIKE 'identifier_with_wildcards'];

注:like通配表达式说明:*表示任意个任意字符,|表示或的关系。

-- 查看以'db'为开头的数据库
show databases like 'db*';

(2)查看数据库信息

DESCRIBE | DESC DATABASE [EXTENDED] db_name;

1)查看基本信息

desc database db_hive3;

2)查看更多信息

desc database extended db_hive3;

3.修改数据库

--修改dbproperties
ALTER DATABASE database_name SET DBPROPERTIES (property_name=property_value, ...);

--修改location
ALTER DATABASE database_name SET LOCATION hdfs_path;

--修改owner user
ALTER DATABASE database_name SET OWNER USER user_name;

注:修改数据库location,不会改变当前已有表的路径信息,而只是改变后续创建的新表的默认的父目录。 

alter database db_hive3 set dbproperties ('create_date'='2023-02-01');

4.删除数据库

DROP DATABASE [IF EXISTS] database_name [RESTRICT|CASCADE];

注:RESTRICT:严格模式,若数据库不为空,则会删除失败,默认为该模式。

       CASCADE:级联模式,若数据库不为空,则会将库中的表一并删除。

drop database db_hive1 restrict ;
drop database db_hive3 cascade ;

5.切换(使用)指定数据库

use database_name;

(二)表操作

1.建表语法

create [external] table [IF NOT EXISTS] table_name
[(colName colType [comment 'comment'], ...)]
[comment table_comment]
[partition by (colName colType [comment col_comment], ...)]
[clustered BY (colName, colName, ...)
[sorted by (col_name [ASC|DESC], ...)] into num_buckets
buckets]
[row format row_format]
[stored as file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
[AS select_statement];


CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS]
[db_name.]table_name
LIKE existing_table_or_view_name
[LOCATION hdfs_path];
1. CREATE TABLE :按给定名称创建表,如果表已经存在则抛出异常。可使用 if not exists 规避; 2. EXTERNAL 关键字:         创建外部表,否则创建的是内部表( 管理表 )         删除内部表时,数据和表的定义(元数据)同时被删除;         删除外部表时,仅仅删除了表的定义(元数据),数据保留;          在生产环境中,多使用外部表; 3. comment :表的注释; 4. partition by :对表中数据进行分区,指定表的分区字段; 5. clustered by :创建分桶表,指定分桶字段; 6. sorted by :对桶中的一个或多个列排序,较少使用。

存储子句:

ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char] -- 字段分隔符
[COLLECTION ITEMS TERMINATED BY char] -- 集合分隔符
[MAP KEYS TERMINATED BY char] -- map分隔符
[LINES TERMINATED BY char] | SERDE serde_name -- 行分隔符
[WITH SERDEPROPERTIES (property_name=property_value,
property_name=property_value, ...)]
AS :后面可以接查询语句,表示根据后面的查询结果创建表。 LIKE like 表名,允许用户复制现有的表结构,但是不复制数据。

查看建表语句:

show create table 表名;

2.内部表

-- 创建内部表

create table t1(
    id int,
    name string,
    hobby array<string>,
    addr map<string,string>
)row format delimited fields terminated by ';'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\\n';
-- 显示表的定义,显示的信息较少
desc t1; 

-- 显示表的定义,显示的信息多,格式友好

desc formatted t1; 
-- 数据源
2;zhangsan;book,TV,code;beijing:chaoyang,shagnhai:pudong
3;lishi;book,code;nanjing:jiangning,taiwan:taibei
4;wangwu;music,book;heilongjiang:haerbin

-- 加载数据

load data local inpath '/opt/stufile/t1.dat' into table t1;
-- 查询数据
select * from t1;

-- 查询数据文件

dfs -cat /opt/soft/hive312/warehouse/mydb.db/t1/t1.dat;


2;zhangsan;book,TV,code;beijing:chaoyang,shagnhai:pudong
3;lishi;book,code;nanjing:jiangning,taiwan:taibei
4;wangwu;music,book;heilongjiang:haerbin

-- 删除表,表和数据同时被删除

drop table t1;

-- 再次查看数据文件,已经被删除

dfs -ls /opt/soft/hive312/warehouse/mydb.db

3.外部表

-- 创建外部表

create external table t2(
    id int,
    name string,
    hobby array<string>,
    addr map<string,string>
)row format delimited fields terminated by ';'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\\n'
location '/opt/lsl';-- 指定外部表的存放目录,如果hdfs没有创建,会自动创建

-- 显示表的定义

desc formatted t2;

-- 加载数据

load data local inpath '/opt/stufile/t1.dat' [overwrite] into table t2;

-- 查询表数据

select * from t2;

-- 查看数据源

dfs -cat /opt/lsl/t1.dat;

-- 删除外部表,表不存在,但是数据还在

drop table t2;
show tables ;
dfs -cat /opt/lsl/t1.dat;

内部表与外部表的区别请查看博文《Hive内部表与外部表的区别具体说明

4.内部表与外部表的转换

(1)内部表转外部表

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

(2)外部表转内部表

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

小结

建表时:
  • 如果不指定external关键字,创建的是内部表;
  • 指定external关键字,创建的是外部表;
删表时:
  • 删除外部表时,仅删除表的定义,表的数据不受影响;
  • 删除内部表时,表的数据和定义同时被删除;
外部表的使用场景:
  • 想保留数据时使用,生产多用外部表。

5.分区表

  1. Hive在执行查询时,一般会扫描整个表的数据。由于表的数据量大,全表扫描消耗时 间长、效率低。
  2. 而有时候,查询只需要扫描表中的一部分数据即可,Hive引入了分区表的概念,将表 的数据存储在不同的子目录中,每一个子目录对应一个分区。只查询部分分区数据时,可避免全表扫描,提高查询效率。
  3. 在实际中,通常根据时间、地区等信息进行分区。

-- 创建分区表

create table if not exists t3
(
    id    int,
    name  string,
    hobby array<string>,
    addr  map<string,string>
) partitioned by (dt string)
    row format delimited fields terminated by ';'
        collection items terminated by ','
        map keys terminated by ':'
        lines terminated by '\\n';

-- 加载数据到对应分区,该语句不需要新建分区

load data local inpath '/opt/stufile/t1.dat' into table t3 partition (dt = '2020-06-01');
load data local inpath '/opt/stufile/t1.dat' into table t3 partition (dt = '2020-06-02');

-- 查看分区

show partitions t3;

-- 新增分区不加载数据

alter table t3 add partition (dt = '2020-06-03');

-- 新增多个分区,不加载数据

alter table t3 add partition (dt = '2020-06-04') partition (dt = '2020-06-05');

-- 新增多个分区,准备数据

dfs -cp /opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-01 /opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-07;

dfs -cp /opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-01 /opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-08;

-- 拷贝后检查是否有数据

dfs -cat /opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-07/t1.dat;

dfs -cat /opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-08/t1.dat;

-- 新增多个分区,加载数据

alter table t3
    add partition (dt = '2020-06-07') location '/opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-07'
        partition (dt = '2020-06-08') location '/opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-08';

-- 查询数据

select * from t3;

 -- 修改分区的hdfs路径

alter table t3
    partition (dt = '2020-06-01') set location '/opt/soft/hive312/warehouse/mydb.db/t3/dt=2020-06-03';

-- 加载数据

load data local inpath '/opt/stufile/t1.dat' into table t3 partition (dt = '2020-06-03');

-- 删除分区:可以删除一个或多个分区,用逗号隔开

alter table t3 drop partition (dt='2020-06-03'),partition (dt='2020-06-04');

-- 动态分区

-- 动态分区的设置
set hive.exec.dynamic.partition=true;-- 是否开启动态分区
set hive.exec.dynamic.partition.mode=nonstrict;-- 设置分区模式为非严格模式

-- 创建一个分区表
create table student_dt
(
    id      int,
    name    string,
    likes   array<string>,
    address map<string,string>
) partitioned by (age int,gender string)-- 指定分区字段
    row format delimited fields terminated by ','
        collection items terminated by '-'
        map keys terminated by ':'
        lines terminated by '\\n';

select *
from studentpt;-- 有数据
select *
from student_dt;-- 没有数据,带分区
-- 将studentpt中的数据导入到student_dt表中
insert into table student_dt partition (age, gender)
select id, name, likes, address, age, gender -- 注意要插入的表的字段名排列
from studentpt;

show partitions student_dt;
/*
分区主要用于提高性能
分区列的值将表划分为一个个的文件夹
查询时语法使用"分区"列和常规列类似
查询时Hive会只从指定分区查询数据,提高查询效率
分为静态分区和动态分区
动态分区建表语句和静态分区相同*/

-- 添加分区
alter table student_dt add partition (age = 28,gender='boy');
alter table student_dt add partition (age = 28,gender='girl');

-- 删除分区,数据也会删除,相当于目录下的文件一并删除
alter table student_dt drop partition (age = 18,gender='boy');

select * from student_dt where age=18 and gender='girl';-- 数据未删除

6.分桶表

        当单个的分区或者表的数据量过大,分区不能更细粒度的划分数据,就需要使用分桶技术将数据划分成更细的粒度。将数据按照指定的字段进行分成多个桶中去,即将数据按照字段进行划分,数据按照字段划分到多个文件当中去。分桶的原理:
  • MR中:key.hashCode % reductTask
  • Hive中:分桶字段hashCode % 分桶个数

-- 创建分桶表

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

-- 创建普通表

create table course_common(
    id int,
    name string,
    score int
)
row format delimited fields terminated by '\\t';

-- 普通表加载数据

load data local inpath '/opt/stufile/course.dat' into table course_common;


1       java    90
1       c       78
1       python  91
1       hadoop  80
2       java    75
2       c       76
2       python  80
2       hadoop  93
3       java    98
3       c       74
3       python  89
3       hadoop  91
5       java    93
6       c       76
7       python  87
8       hadoop  88

注:数据之间不是空格,而是Tab键

-- 通过 insert ... select ... 给桶表加载数据

insert into table course select * from course_common;

-- 查看分桶表

dfs -ls /opt/soft/hive312/warehouse/mydb.db/course;

-- 第一个分区:id%3=0

dfs -cat /opt/soft/hive312/warehouse/mydb.db/course/000000_0;

-- 第二个分区:id%3=1

dfs -cat /opt/soft/hive312/warehouse/mydb.db/course/000001_0;

-- 第三个分区:id%3=2

dfs -cat /opt/soft/hive312/warehouse/mydb.db/course/000002_0;

备注: 分桶规则: 分桶字段.hashCode % 分桶数 分桶表加载数据时,使用 insert... select ... 方式进行 网上有资料说要使用分区表需要设置 hive.enforce.bucketing=true ,是 Hive1.x 以前的版本; Hive 2.x 中,删除了该参数,始终可以分桶;

7.高级建表语句

 -- CTAS方法将查询结果插入到表中

create table ctas_student as select * from student where id>5;

-- CTE(WITH语句)创建临时表

(CTAS with Common Table Expression)

临时表的生命周期是当前session生命周期

表只对当前session有效,session退出后自动删除
表空间位于/tmp/hive-<user_name>(安全考虑)
如果创建的临时表表名已存在,实际用的是临时表

-- 创建临时表:当前会话断开就消失
create table test_2 as
with t1 as (select * from student_wb where id < 5),
     t2 as (select * from student_wb where id between 5 and 10),
     t3 as ( select * from student_wb where id >10)
select * from t1 union all select * from t2 union all select * from t3;
show create table cte_table;

select * from cte_table;

-- LIKE创建的表结构一样

create table student_like like student;
select * from student_like;

8.修改表与删除表

--修改表名

alter table course_common rename to course_common1;
-- 修改列名
alter table course_common1 change column id cid int;

-- 修改字段类型

alter table course_common1 change column cid cid string;
注:修改字段数据类型时,要满足数据类型转换的要求。如 int 可以转为 string ,但是string 不能转为 int。 -- 增加字段,默认数据为null
alter table course_common1 add columns (common string);

-- 替换字段,列名全部替换掉

alter table test replace columns (stu_age int,name string);

-- 删除字段

alter table course_common1 replace columns (id string,cname string,score int);

注:这里仅仅只是在元数据中删除了字段,并没有改动hdfs上的数据文件

-- 删除表
drop table course_common1;

(三)数据操作

1.数据导入

LOAD DATA [LOCAL] INPATH 'filepath'
[OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1,
partcol2=val2 ...)]
LOCAL LOAD DATA LOCAL ... 从本地文件系统加载数据到Hive表中,本地文件会拷贝到Hive表指定的位置; LOAD DATA ... 从HDFS加载数据到Hive表中,HDFS文件移动到Hive表指定的位置 INPATH :加载数据的路径 OVERWRITE :覆盖表中已有数据;否则表示追加数据 PARTITION :将数据加载到指定的分区

-- 创建表

CREATE TABLE tabA
(
    id   int,
    name string,
    area string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

-- 加载本地文件到hive(tabA),本地文件会拷贝到表中

load data local inpath '/opt/stufile/sourceA.txt' into table tabA;

1,fish1,SZ
2,fish2,SH
3,fish3,HZ
4,fish4,QD
5,fish5,SR

-- 查看tabA数据

select * from tabA;

-- 本地文件还在

-- 加载hdfs文件到hive(tabA),本地文件会移动到表中

load data inpath '/data/sourceA.txt' into table tabA;
-- 检查hdfs文件,已经被转移
dfs -cat /data/sourceA.txt;

-- 加载数据覆盖表中已有数据

load data local inpath '/opt/stufile/sourceA.txt' overwrite into table tabA;
-- 创建表时加载数据
dfs -mkdir /data/tabB;
dfs -put /opt/stufile/sourceA.txt /data/tabB;
dfs -cat /data/tabB/sourceA.txt;

create table tabB
(
    id   int,
    name string,
    area string
) row format delimited fields terminated by ','
    location '/data/tabB';

select * from tabB;

2.插入数据

-- 创建分区表

create table tabC(
    id int,
    name string,
    area string
)partitioned by (month string)
row format delimited fields terminated by ',';

-- 插入数据

insert into tabC partition (month = '202301')
values (1, 'zhangsan', 'BJ'),
       (2, 'lisi', 'SH'),
       (3, 'wangwu', 'NJ');

-- 结果

-- 插入查询的结果数据

insert into tabC partition (month = '202302')
select id, name, area
from tabC
where month = '202301';

-- 结果

 -- 多表(多分区)插入模式

from tabC insert overwrite table tabC partition (month = '202303')
select id, name, area where month = '202302'
insert overwrite table tabC partition (month = '202304')
select id, name, area where month = '202302';

-- 结果

-- 创建表并插入数据(as select)

insert overwrite local directory '/opt/stufile/tabC' select * from tabC where month='202304';

-- 结果

[root@lxm147 ~]# cat /opt/stufile/tabC/000000_0 
1zhangsanBJ202304
2lisiSH202304
3wangwuNJ202304

-- 将查询结果格式化输出到本地

insert overwrite local directory '/opt/stufile/tabC2'
row format delimited fields terminated by ' '
select * from tabC;

-- 结果

[root@lxm147 ~]# cat /opt/stufile/tabC2/000000_0 
1 zhangsan BJ 202301
2 lisi SH 202301
3 wangwu NJ 202301
1 zhangsan BJ 202302
2 lisi SH 202302
3 wangwu NJ 202302
1 zhangsan BJ 202303
2 lisi SH 202303
3 wangwu NJ 202303
1 zhangsan BJ 202304
2 lisi SH 202304
3 wangwu NJ 202304

3.数据导出

-- 将查询结果导出到hdfs

insert overwrite directory '/data/tabC3'
row format delimited fields terminated by ' '
select * from tabC;

-- 结果

dfs -cat /data/tabC3/000000_0;

 -- dfs 命令导出数据到本地。本质是执行数据文件的拷贝

dfs -get /data/tabC3/000000_0 /opt/stufile/tabC4;

[root@lxm147 ~]# cat /opt/stufile/tabC4
1 zhangsan BJ 202301
2 lisi SH 202301
3 wangwu NJ 202301
1 zhangsan BJ 202302
2 lisi SH 202302
3 wangwu NJ 202302
1 zhangsan BJ 202303
2 lisi SH 202303
3 wangwu NJ 202303
1 zhangsan BJ 202304
2 lisi SH 202304
3 wangwu NJ 202304

​-- hive 命令导出数据到本地。执行查询将查询结果重定向到文件

[root@lxm147 ~]# hive -e "select * from mydb.tabC" > /opt/stufile/a.log;

[root@lxm147 ~]# cat /opt/stufile/a.log 
tabc.id	tabc.name	tabc.area	tabc.month
1	zhangsan	BJ	202301
2	lisi	SH	202301
3	wangwu	NJ	202301
1	zhangsan	BJ	202302
2	lisi	SH	202302
3	wangwu	NJ	202302
1	zhangsan	BJ	202303
2	lisi	SH	202303
3	wangwu	NJ	202303
1	zhangsan	BJ	202304
2	lisi	SH	202304
3	wangwu	NJ	202304

-- export 导出数据到HDFS。使用export导出数据时,不仅有数还有表的元数据信息

export table tabC to '/data/tabC4';

dfs -ls /data/tabC4;

-- export 导出的数据,可以使用 import 命令导入到 Hive 表中 -- 使用 like tname 创建的表结构与原表一致。 create ... as select ...结构可能不一致
create table tabE like tabc;
import table tabE from '/user/hadoop/data/tabC4'; 

-- 截断表,清空表中的数据(注意:仅能操作内部表)

truncate table tabB;
小结: 数据导入: load data / insert / create table .... as select ..... / import table 数据导出: insert overwrite ... diretory ... / hdfs dfs -get / hive -e "select ..." > a.log / export table ... Hive 的数据导入与导出还可以使用其他工具: Sqoop DataX 等;

三、DQL命令

1.DQL语法

HQL与SQL的查询语句差别不大,在这里只说明不一样的地方

SELECT [ALL | DISTINCT] select_expr, select_expr, ...
  FROM table_reference       -- 从什么表查
  [WHERE where_condition]   -- 过滤
  [GROUP BY col_list]        -- 分组查询
   [HAVING col_list]          -- 分组后过滤
  [ORDER BY col_list]        -- 排序
  [CLUSTER BY col_list
    | [DISTRIBUTE BY col_list] [SORT BY col_list]
  ]
 [LIMIT number]                -- 限制输出的行数

2.字段名重命名——中文别名要用反引号,且as可有可无

select
    t.deptno,
    avg(t.sal) as `平均工资`
from emp t
group by t.deptno;

3.join on——Hive仅支持等值连接

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

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

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

满外连接:将会返回所有表中符合where语句条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用null值替代。

full outer join全外连接,连接两张表都没有的部分。

交叉连接(笛卡尔积):cross join(比如左表有100条,右表有1条,不耗费性能)

JOIN发生在where子句之前

select 
    e.empno, 
    e.ename, 
    d.deptno 
from emp e 
full join dept d 
on e.deptno = d.deptno;

4.排序

(1)order by——全局排序

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

Sort By:对于大规模的数据集order by的效率非常低。在很多情况下,并不需要全局排序,此时可以使用Sort by

Sort by为每个reduce产生一个排序文件。每个Reduce内部进行排序,对全局结果集来说不是排序。

-- 设置reduce个数
set mapreduce.job.reduces =3;

-- 查看设置reduce个数
set mapreduce.job.reduces;

-- 根据部门编号降序查看员工信息
select * from emp sort by deptno desc;

-- 将查询结果导入到文件中(按照部门编号降序排序)
insert overwrite local directory '/opt/atguigu/sortby-result'
select * from emp sort by deptno desc;

(3)分区(Distribute By)

Distribute By:在有些情况下,我们需要控制某个特定行应该到哪个Reducer,通常是为了进行后续的聚集操作。distribute by子句可以做这件事。distribute by类似MapReduce中partition(自定义分区),进行分区,结合sort by使用。 

对于distribute by进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。

(4)分区排序(Cluster By)

当distribute by和sort by字段相同时,可以使用cluster by方式。

cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是序排序,不能指定排序规则为asc或者desc。

select * from emp cluster by deptno;

等同于

select * from emp distribute by deptno sort by deptno;

5.UNION

ORDER BY, SORT BY, CLUSTER BY, DISTRIBUTE BY 和LIMIT适用于合并后的整个结果
集合其他操作可以使用JOIN/OUTER JOIN来实现。

四、Hive函数

1.查看所有的函数

show function;-- 查看系统内置函数

show function like '*string';-- 查看有关字符串的函数

desc function substr; -- 查看内置函数用法

desc function extended substr; -- 查看内置函数详细信息

2.日期函数

3.数学函数

4.流程控制函数

select 
    stu_id,
    course_id,
    case
        when score>=90 then 'A'
        when score>=80 then 'B'
        when score>=70 then 'C'
        when score>=60 then 'D'
        else '不及格'
    end
from score_info;

-- 等同于,仅限于同一个字段的等值判断

select 
    stu_id,
    course_id,
    case score
        when 90 then 'A'
        when 80 then 'B'
        when 70 then 'C'
        when 60 then 'D'
        else '不及格'
    end
from score_info;

-- 查询每个岗位男女各多少人
select job,
       sum(`if`(sex = '男', 1, 0)) male,
       sum(`if`(sex = '女', 1, 0)) female
from employee
group by job;

select job,
       sum(case when sex = '男' then 1 else 0 end) male,  --男性人口
       sum(case when sex = '女' then 0 else 1 end) female --女性人口
from employee
group by job;

5.高级聚合函数以上是关于Hive(五)DML数据操作的主要内容,如果未能解决你的问题,请参考以下文章

Hive学习——DDL&DML&DQL语句

打怪升级之小白的大数据之旅(六十四)<Hive旅程第五站:DML基本操作>

打怪升级之小白的大数据之旅(六十四)<Hive旅程第五站:DML基本操作>

Hive:第 5章 DML 数据操作

008-Hadoop Hive sql语法详解3-DML 操作:元数据存储

Hive的DML操作