Hive入门(3)

1.DML补充

(1)查询出不包含xx的数据

select * from emp where ename not in ('SCOTT');


//查询不包含ename等于SCOTT的所有行

(2)查询出指定的某行

 select * from emp where ename in ('SCOTT','ss');

查询返回ename =  SCOTT 和 ss的行 

(3)查询某一区间的行 between  and  【这是一个闭区间】

select * from emp where salary between 1000 and 3000;
OK
7499	ALLEN	SALESMAN	7698	1981-2-20	1600.0	300.0	30
7521	WARD	SALESMAN	7698	1981-2-22	1250.0	500.0	30

2.聚合函数

(1)定义:具有多进一出操作的函数。例如max/min/count/avg/sum

select min(salary),max(salary),avg(salary),sum(salary) from emp;


 select count(1) from emp where depto=10;



count(1)  count(*)  count(字段) 区别


count(*),count(1)是一样的

count("字段名"):如果字段为非空字段那么它和count(1),count(*)是一样的

但如果是可以为空的字段,查询时间将会长很多

3.分组函数  group by

(1)需求:求每个部门的平均工资

select deptno,avg(salary) from emp group by deptno;


这里注意一点,select 出现的字段,如果没有出现组函数中(就是那些count,avg。。。),
必须出现在group by 函数中。

(2)需求:求每个部门每个工作的最高工资

select deptno,job,avg(salary) from emp group by deptno,job;

//好像聚合函数和其他字段一起使用时,必须和分区函数一起使用。

(3)需求:求每个部门,平均工资大于2000的

 select deptno,avg(salary) from emp group by deptno having avg(salary)>2000;


//这里用where是会报错的

where是从数据表中的字段单条直接进行筛选,having是对分组后的结果,整体进行筛选,where需在group 之前,数据先筛选。

(4)给数据加个标签

select ename,salary,
case 
when salary>1 and salary<=1000 then 'lower'
when salary>1000 and salary<=2000 then 'middle'
when salary>2000 and salary<=4000 then 'high'
else 'highest'
end
from emp;


//select xx case when xxx条件 and xxx条件 then '标签名' end  from tablename;

4.join(关联查询)

(1)join=inner join

select * from joina join joinb;



这个产生的笛卡儿积,俩者的数据都做了join,这是什么消耗性能的!!!

(2)left join

select * from joina left join joinb on joina.id=joinb.id;


OK
1	ruoze	1	30
2	jepson	2	29
3	yunfei	NULL	NULL

(3)right join

 select joina.id,joina.name from joina right join joinb on joina.id = joinb.id;

1	ruoze
2	jepson
NULL	NULL

(3)full join

select * from joina full join joinb on joina.id=joinb.id;

1	ruoze	1	30
2	jepson	2	29
3	yunfei	NULL	NULL
NULL	NULL	4	20

5.单级分区表(partition)

(1)分区表的作用和意义:在查询处理的时候,加上分区位置,能大大降低reduce io   。

(2)创建静态分区表:

create table order_partition(ordernumber string,orderevent string) partitioned by (eventdate string) row
    > format delimited fields terminated by '\t';


注意这个partitioned by

(3)根据分区表查询

select * from order_partition where eventdate='2018-12';

(4)如果将数据直接放到HDFS上的Hive分区下面,能不能查询到呢?

测试:

[root@hadoop01 data]#hdfs dfs -mkdir /user/hive/warehouse/order_partition/eventdate=2018-01/
18/12/27 21:41:15 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[root@hadoop01 data]#hdfs dfs -put /home/hadoop/data/order.txt /user/hive/warehouse/order_partition/eventdate=2018-01/
18/12/27 21:41:38 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[root@hadoop01 data]#hdfs dfs -ls /user/hive/warehouse/order_partition/eventdate=2018-01/
18/12/27 21:41:55 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 1 items
-rw-r--r--   1 root root        192 2018-12-27 21:41 /user/hive/warehouse/order_partition/eventdate=2018-01/order.txt
[root@hadoop01 data]#

结果:查询不到的,因为根本在元数据库,根本就没有关于这个新分区的信息,该怎么办呢?

(5)刷新分区解决上述问题

这里用的alter命令,而没用msck命令,因为这个命令是全局更新,十分废时间,慎用。
 

hive> select * from order_partition where eventdate=2018-01;
OK
Time taken: 0.799 seconds
hive> select * from order_partition where eventdate=2018-02;
OK
Time taken: 0.124 seconds
hive> select * from order_partition where eventdate='2018-02';
OK
Time taken: 0.109 seconds
hive> select * from order_partition where eventdate='2018-01';
OK
Time taken: 0.085 seconds
hive> alter table order_partition add if not exists partition(eventdate='2018-01');
OK
Time taken: 0.138 seconds
hive> select * from order_partition where eventdate='2018-01';
OK
160202412041    2018-12-24      09:21:21.335+01	NULL	2018-01
160703140214    2018-10-01      13:42:34.224+02	NULL	2018-01
161102412241    2018-11-14      19:21:21.25+03	NULL	2018-01
160470314022    2018-05-02      14:32:14.21+01	NULL	2018-01


这里做了个测试发现,hdfs上那新创建的文件夹就是你的分区名字,也就是换成02就刷新不了,因为根本就没有这文件。

(6)除了上述这种手动的,添加数据和分区,还有一种方法,添加分区和数据


create table order_4_partition(
ordernumber string,
eventtime string
)
row format delimited fields terminated by '\t';
load data local inpath '/home/hadoop/data/order.txt' overwrite into table order_4_partition;

//这俩个事创建表然后加载数据
insert overwrite table order_partition 
partition(eventdate='2014-08')
select * from order_4_partition;

//增加了08分区,然后将数据复制覆盖过去。

以上讲的都是单级分区

6.多级分区表

(1)创建多分区表

 create table order_mulit_partition(ordernumber string,eventtime string) partitioned by (event_month string,event_day string)
row format delimited fields terminated by '\t';


可以看出其实和单级分区表就是变成了多个列

(2)多分区加载数据

LOAD DATA LOCAL INPATH '/home/hadoop/data/order.txt' 
OVERWRITE INTO TABLE order_mulit_partition 
PARTITION(event_month='2018-05', event_day='01'); 

区别也只是要指定俩个分区
在HDFS上就是有在月文件夹下面还有个天文件夹

(3)查询也是一样的,加个分区。

7.动态分区

(1)需求:将emp表中的数据按照部门编号10和20.。。。。分区到其它表

create table ruozedata_static_emp 
(empno int, ename string, job string, mgr int, hiredate string, salary double, comm double)
PARTITIONED by(deptno string)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t' ;

//先创建一个分区表
insert into table ruozedata_static_emp partition(deptno='10')
select empno,ename,job,mgr,hiredate,salary,comm from emp
where deptno=10;
按部门编号十来分

insert into table ruozedata_static_emp partition(deptno='20')
select empno,ename,job,mgr,hiredate,salary,comm from emp
where deptno=20;
按部门编号20来分

如果是1000个呢?那不得敲死,这就引出来了动态分区

(2)创建动态分区表


create table ruozedata_dynamic_emp 
(empno int, ename string, job string, mgr int, hiredate string, salary double, comm double)
PARTITIONED by(deptno string)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t' ;

和静态一样的

(3)动态分区

先设置 set hive.exec.dynamic.partition.mode=nonstrict(注意这只是当前窗口模式有效,永久去hive-site设置,这也是hive设置语法的方式,key=value,set key表示查看这个key的值),将动态分区设置成非严格的方式,然后再执行

8.Function

(1)查看自带的内置函数

show functions;


desc function extended upper;

查看这方法的具体使用方法;

(2)使用举例,不会用desc function extended name ;查看example

select unix_timestamp() from emp;
查看当前的时间戳
select current_date from emp;
查看当前的日期
还有day month hour  minute

select date_add("2018-12-01",10) from emp;
日期天数加三
select date_sub("2018-12-01",10) from emp;
日期天数减三

 select substr('HIVE',1,3) from emp;
截取字符串的用法
还有连接字符concat
还有concat_ws//多个转一个


SELECT concat_ws('.', 'www', array('facebook', 'com')) FROM src LIMIT 1;
  'www.facebook.com'

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值