from --map阶段
join --map(有map端join)或者reduce(reduce join)
on
where --map端
group by --reduce阶段
having --reduce端
select --reduce端(或者map端)
order by --reduce端
limit --reduce端(或者map端)
基础数据类型:
支持mysql或者oracle的数据类型。
size只支持map array
arr的函数较为丰富
结构体和array的区别
数组只能是某一类型的集合
结构体和array的区别:
数组只能是某种类型的元素集合,但是结构体可以任意类型。
arr的函数较为丰富内部函数,strcut较少些
两者取值不一样,arr使用角标取值,而struct使用属性名取值
hive文件存储格式包括以下几类:
1、TEXTFILE
2、SEQUENCEFILE
3、RCFILE
4、ORCFILE(0.11以后出现)
其中TEXTFILE为默认格式,建表时不指定默认为这个格式,导入数据时会直接把数据文件拷贝到hdfs上不进行处理;
SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接从本地文件导入数据,数据要先导入到textfile格式的表中, 然后再从表中用insert导入SequenceFile,RCFile,ORCFile表中。
嵌套??
所有元素分割符自己调(搜:hive的map类型处理)
hive共支持8个层级的分隔符,依次是:
\001,\002,\003,...\008
map嵌套使用
uid uname belong tax addr
1 xdd wuxian:(300,300),gongjijin:1200,1500,shebao:300,
2 lkq wuxian:200,300,gongjijin:1000,1200,shebao:200
create table qt(
id int,
name string,
addr map>
)
row format delimited fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
;
内置函数:
显示所有函数:
show functions;
查看函数描述:
desc func_name;
模糊查找hive的函数:
show functions like '*concat*';
rand(7) ;随机
说明:返回一个0到1范围内的随机数。如果指定种子seed,则会等到一个稳定的随机数序列
round(double,n);取多少位小数 四舍五入
split(str,spliter);
substr(str,start,end) 或者 substring()
size(arr/map) length(str)
concat(str,str.....)
concat_ws(分隔符,str,str1.......)
concat_ws(seprater,str,str1..) : 输入类型一定是字符串或者数组
cast(col as type)
if(condition,true,false)
case col
when value then ...
when value1 then ...
else
...
end
case
when col=value then ...
when col=value1 then ...
else
...
end
if(condition,true,false)
select if(1=2,"男",if(1=3,"妖","女"));
select
id,
if(1=id,"男",if(2=id,"女","妖"))
from u1
;
case col
when value then ...
when value1 then ...
else
...
end
select
id,
(
case id
when 1 then "男"
when 2 then "女"
else
"妖"
end) sl
from u1
;
case
when col=value then ...
when col=value1 then ...
else
...
end
select
id,
(
case
when id=1 then "男"
when id=2 then "女"
else
"妖"
end) sl
from u1
;
is null
is not null
nvl(val,default_value) : val为空则返回default
from_unixtime():返回unix时间
unix_timestamp;返回时间戳
to_date():
datediff
date_sub
date_add
last_day
next_day
current_date:
current_timestamp:
hour()
week()
mimint()
1.日期比较函数: datediff语法: datediff(string enddate,string startdate)
返回值: int
说明: 返回结束日期减去开始日期的天数。
举例:
hive> select datediff('2016-12-30','2016-12-29');
1
2.日期增加函数: date_add语法: date_add(string startdate, intdays)
返回值: string
说明: 返回开始日期startdate增加days天后的日期。
举例:
hive>select date_add('2016-12-29',10);
2017-01-08
3.日期减少函数: date_sub语法: date_sub (string startdate,int days)
返回值: string
说明: 返回开始日期startdate减少days天后的日期。
举例:
hive>select date_sub('2016-12-29',10);
2016-12-19
4.查询近30天的数据
select * from table where datediff(current_timestamp,create_time)<=30;
create_time 为table里的字段,current_timestamp 返回当前时间 2018-06-01 11:00:00
=====================================================
show functions;
desc func_name;
coalesce(v1,v2,v3....) 返回第一个不为空的参数
xpath():返回xml nodes
show function like 'concat'
[外链图片转存失败(img-juqjeaT6-1568968991249)(D:/新机/千峰笔记/1568173412359.png)]
trim
ltrim
hive> select ltrim(" sdjfk dsfs ""sdfsdf");
OK
sdjfk dsfs sdfsdf
Time taken: 0.149 seconds, Fetched: 1 row(s)
hive> select trim(" sdjfk dsfs ""sdfsdf");
lpad():左补足
lpad():左补足
replace(str,'',''):
substring_index(str,'a',2):指定索引位置
initcap():首字符变大写
find_in_set():查找是否在set中,费性能
str_to_map():转map
get_json_object():获取json对象
Possible choices: _FUNC_(string, string)
regexp_extract(str,reg,2):正则抽取 ()()()
regexp_replace(str,'',''):正则替换
parse_url():解析url
size(a1):
length(str):
map_keys()
map_values()
mv.["k1"]
mv.[0]
mv.k1
initcap()
initcap(str)——返回str,每个单词的第一个字母都是大写的,所有其他字母都是小写的。单词由空格分隔。
collect_set():
collect_list():
explode
爆炸(a)——将数组a的元素分成多行,或者将映射的元素分成多行和多列
explode(a) - separates the elements of array a into multiple rows, or the elements of a map into multiple rows and columns
cast():
binary():转换为二进制
select empno,ename,job,mgr,hiredate,sal, COALESCE(comm, 0),deptno from emp;
应用场景:
求出分组内的统计、排名、自增
聚合函数和窗口函数的区别:
1集合函数是多行返回一行
2窗口函数可以达到1行返回一行或者多行返回一行
over(partition by a,b)
count(a) over(partition a,b order by a desc)
count(a) over(order by a desc)
窗口:分为物理窗口
sum() over()
avg() over()
窗口:逻辑窗口
1 23 23
1 35 58
1 12 70
聚合函数和窗口函数区别:
1、聚合函数是一般是多行 返回一行,窗口函数可以达到1行返回一行或者多行返回一行
over(partition by a,b)
count(a) over(partition by a,b order by a desc)
count(a) over(order by a desc)
窗口:物理窗口和逻辑窗口
物理窗口:rows
逻辑窗口:range
语法:
ROWS/range between [CURRENT ROW | UNBOUNDED PRECEDING | [num] PRECEDING] AND [UNBOUNDED FOLLOWING | [num] FOLLOWING| CURRENT ROW]
sum() over():
count() over()
avg() over()
...over()
first_value
last_value
lag
LAG (scalar_expression [,offset] [,default]) OVER ([query_partition_clause] order_by_clause); The LAG function is used to access data from a previous row.
滞后(scalar_expression [,offset] [,default])超过([query_partition_clause] order_by_clause);滞后函数用于访问前一行中的数据。
lead
LEAD (scalar_expression [,offset] [,default]) OVER ([query_partition_clause] order_by_clause); The LEAD function is used to return data from the next row.
将(scalar_expression [,offset] [,default])连接到([query_partition_clause] order_by_clause);LEAD函数用于从下一行返回数据。
ntile
NTILE(n)
用于将分组数据按照顺序切分成n片,返回当前记录所在的切片值
NTILE不支持ROWS BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
如果切片不均匀,默认增加第一个切片的分布
经常用来取前30% 带有百分之多少比例的记录什么的
-- 1 把记录按价格顺序拆分成10片
drop table if exists test_dp_price_rk;
create table test_dp_price_rk
as
select
id,
price,
NTILE(10) OVER (order by price desc) as rn
from test_dp_price;
-- 2 按片取30%和70%,分别计算平均值
select
new_rn,
max(case when new_rn=1 then 'avg_price_first_30%' when new_rn=2 then 'avg_price_last_70%' end) as avg_price_name,
avg(price) avg_price
from
(
select
id,
price,
rn,
case when rn in (1,2,3) then 1 else 2 end as new_rn
from test_dp_price_rk
)a
group by new_rn;
案例:
create table if not exists win(
name string,
class string,
score int
)
row format delimited fields terminated by ' '
;
load data local inpath '/home/hivedata/win' into table win;
逻辑:
select
name,
class,
score,
sum(score) over(order by score range between 5 preceding and 5 following) mm
from win;
物理:
select
name,
class,
score,
sum(score) over(order by score rows between 2 preceding and 3 following) mm
from win;
每个班前一名和其后一名的分差:
select
name,
class,
score,
(score-lag(score,1) over(partition by class order by score asc)) diff
from win;
每个班前一名和其后一名的分差:
select
name,
class,
score,
(score-lag(score,1) over(partition by class order by score asc)) diff
from win;
第一个和最后一个值:
select
name,
class,
score,
first_value(score) over(partition by class order by score) first,
last_value(score) over(partition by class order by score) last
from win;
[外链图片转存失败(img-kmBBz84t-1568968991250)(D:/新机/千峰笔记/1568184125984.png)]
基本聚合:group by
高级聚合 grouping sets、with cube、with
group by :
grouping sets() : 指定分组
with cube: 数据魔方,任意维度的组合查询
with rollup :
首先,hive一般分为基本聚合和高级聚合,而基本聚合就是常见的group by,而高级聚合就是grouping sets、with cube、with rollup等。一般group by与hive内置的聚合函数max、min、count、sum、avg等搭配使用。而cube和rollup则更多参考oracle的cube和rollup聚合而来,从hive 0.10.0版本后开始支持。
需求:求每位学员的每次考试的成绩与上一次的成绩对比
lag(score,2) -- 取出前n行的数据
lead(score,2) -- 取出后n行的数据
select
dt,
name,
score,
lag(score,1) over(distribute by name sort by dt asc) as upscore
from stu_score
;
row_number() over()
rank()
dense_rank()
三者区别:
row_number() over() : 排名函数,名次不会重复,适合于生成主键或者不并列排名
rank() over() : 排名函数,有并列名次,名次不连续。如:1,1,3
dense_rank() over() : 排名函数,有并列名次,名次连续。如:1,1,2
案例:
根据class分组,并根据score排名:
select
class,
name,
score,
row_number() over(distribute by class sort by score desc) rn,
rank() over(distribute by class sort by score desc) rk,
dense_rank() over(distribute by class sort by score desc) drk
from win
;
计算每一个班级的前2名:
select
tmp.*
from (
select
class,
name,
score,
row_number() over(distribute by class sort by score desc) rn,
rank() over(distribute by class sort by score desc) rk,
dense_rank() over(distribute by class sort by score desc) drk
from win) tmp
where tmp.rn < 3
;
分组的意思,使用GROUP BY时,除聚合函数外其他已选择列必须包含在GROUP BY子句中,否则会报错。
求某天、某公司、某部门的员工数量:
select
class,
score,
count(*)
from win
group by class,score
;
结果:
1 80 1
1 95 2
2 74 1
2 92 1
3 45 1
3 55 1
3 78 1
3 99 2
select empno,ename,job,mgr,hiredate,sal, COALESCE(comm, 0),deptno from emp;
注意:
1、有group by时,查询字段要么在group by子句中,要么在聚合函数中。
2、group by与聚合函数搭配使用,但是聚合函数不能嵌套使用,如sum(count(*))。
3、如果group by的列值中有null,则包含该null的行将在聚合时被忽略。为了避免这种情况,可以使用COALESCE来将null替换为一个默认值。
4、group by与聚合函数count()搭配使用时,同时COUNT又和DISTINCT搭配使用时,Hive将忽略对reducer个数的设置(如:set mapred.reduce.tasks=20;), 仅会有一个reducer!!!此时reduce将成为瓶颈,这时我们可以使用子查询的方式解决该问题,同时子查询需要别名。
5、collect_set() 和collect_list() 不是聚合函数,不需要和group by搭配使用
grouping sets可以实现对同一个数据集的多重group by操作。事实上grouping sets是多个group by进行union all操作的结合,它仅使用一个stage完成这些操作。grouping sets的子句中如果包换()数据集,则表示整体聚合。多用于指定的组合查询。
例:
1、grouping sets(a,b) ==> group by a union all group by b
2、grouping sets(a,b,(a,b) ==> group by a union all group by b union all group by a,b
3、grouping sets(a,b,(a,b),()) ==>group by a union all group by b union all group by a,b union all 无group by语句
group by class
group by score
group by class,score
例1、
select
class,
NULL as score,
count(*)
from win
group by class
union all
select
NULL AS class,
score,
count(*)
from win
group by score
union all
select
class,
score,
count(*)
from win
group by class,score
;
==如上的语句等价于如下的语句
select
class,
score,
count(*)
from win
group by class,score
grouping sets(class,score,(class,score))
;
上面两个语句的结果都如下:
NULL 45 1
NULL 55 1
NULL 74 1
NULL 78 1
NULL 80 1
NULL 92 1
NULL 95 2
NULL 99 2
1 NULL 3
2 NULL 2
3 NULL 5
1 80 1
1 95 2
2 74 1
2 92 1
3 45 1
3 55 1
3 78 1
3 99 2
数据立方,
cube俗称是数据立方,它可以时限hive任意维度的组合查询。即使用with cube语句时,可对group by后的维度做任意组合查询,如:group a,b,c with cube ,则它首先group a,b,c 然后依次group by a,c 、 group by b,c、group by a,b 、group a 、group b、group by c、group by () 等这8种组合查询,所以一般cube个数=2^3个。2是定值,3是维度的个数。多用于无级联关系的任意组合查询。
例1、
select
class,
score,
count(*)
from win
group by class,score
with cube
;
==如上语句等价于如下
select
class,
score,
count(*)
from win
group by class,score
grouping sets(class,score,(class,score),())
;
结果如下:
NULL NULL 10
NULL 45 1
NULL 55 1
NULL 74 1
NULL 78 1
NULL 80 1
NULL 92 1
NULL 95 2
NULL 99 2
1 NULL 3
1 80 1
1 95 2
2 NULL 2
2 74 1
2 92 1
3 NULL 5
3 45 1
3 55 1
3 78 1
3 99 2
注意:
如上的实现,如果采用传统的group by加union all的方式实现,那就是写得更复杂,大家可以尝试写一写。
卷起的意思,俗称层级聚合,相对于grouping sets能指定多少种聚合,而with rollup则表示从左往右的逐级递减聚合,如:group by a,b,c with rollup 等价于 group by a, b, c grouping sets( (a, b, c), (a, b), (a), ( )).直到逐级递减为()为止,多适用于有级联关系的组合查询,如国家、省、市级联组合查询。
例1、
select
class,
score,
count(*)
from win
group by class,score
with rollup
;
==上面语句等价于如下语句
select
class,
score,
count(*)
from win
group by class,score
grouping sets((class,score),class,())
;
结果如下:
NULL NULL 10
1 NULL 3
1 80 1
1 95 2
2 NULL 2
2 74 1
2 92 1
3 NULL 5
3 45 1
3 55 1
3 78 1
3 99 2
注意:
如上的实现,也可以采用传统的group by加union all来实现,大家可以尝试。
hive.map.agg=true; #最好将其设置为true,因为会用到ma端聚合。
hive.new.job.grouping.set.cardinality=30; #在grouping sets/cube/rollup中是否启用新的job来执行,主要是因为如果分组多而造成数据立方体炸裂,适当设置该阀值,默认为30.
自定义函数:
hive的内置函数满足不了所有的业务需求。
hive提供很多的模块可以自定义功能,比如:自定义函数、serde、输入输出格式等。
常见的自定义函数:
udf:用户自定义函数,user defined function。一对一的输入输出。(最常用的)。
udaf:用户自定义聚合函数。user defined aggregate function。多对一的输入输出。
udtf:用户自定义表生成函数。user defined table-generate function.一对多的输入输出。
udf:一对一的输入输出(常用)
udaf:多对一的输入输出
udtf:一对多的输入输出
编写:
1、继承UDF,重写evaluate(),允许重载。(常用)
2、继承genericUDF,重写initlizer()、getdisplay()、evaluate()。
案例:
> add jar /home/hadoop_learn-1.0.jar;
> create temporary function my_concat as 'com.ali.udf.FirstUdf';
> show functions like *my_c*;
hive> show functions like '*my_c*';
OK
my_concat
> select my_concat('a','b');
> select my_concat(class,name),score from win;
永久:
> create function my_concat as 'com.ali.udf.FirstUdf' using jar hdfs://hadoop01:9000/hadoop_learn-1.0.jar;
将udf的包上传到指定位置。
以后每次将会加载方法。
注意,该方式将会使用库名.函数名。
CREATE TABLE test (
id string,
hivearray array,
hivemap map)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ("field.delim"="[,]","collection.delim"=":","mapkey.delim"="@");
添加函数
法一:
> add jar /home/hadoop_learn-1.0.jar;
> create temporary function my_concat as 'com.ali.udf.FirstUdf';
> show functions like *my_c*;
hive> show functions like '*my_c*';
OK
my_concat
> select my_concat('a','b');
> select my_concat(class,name),score from win;
法二:(永久)
> create function my_concat as 'Udf.DateYear' using jar 'hdfs://hadoop-01:9000/math/my_datayear.jar';
将udf的包上传到指定位置。
以后每次将会加载方法。
注意,该方式将会使用库名.函数名。
法三:
将如下两行语句放到hive的根目录的bin目录下的hive-init
add jar /home/hadoop_learn-1.0.jar;
create temporary function my_concat as 'com.ali.udf.FirstUdf';
每次连接就需要使用hive -i ./hive-init
法四:
将如下两行语句放到hive的根目录的bin目录下的.hiverc
add jar /home/hadoop_learn-1.0.jar;
create temporary function my_concat as 'com.ali.udf.FirstUdf';
每次连接就需要使用hive
法五:源码编译
法一:
> add jar /home/hadoop_learn-1.0.jar;
> create temporary function my_concat as 'com.ali.udf.FirstUdf';
> show functions like *my_c*;
hive> show functions like '*my_c*';
OK
my_concat
> select my_concat('a','b');
> select my_concat(class,name),score from win;
法二:(永久)
> create function my_concat as 'Udf.DateYear' using jar 'hdfs://hadoop-01:9000/math/my_datayear.jar';
将udf的包上传到指定位置。
以后每次将会加载方法。
注意,该方式将会使用库名.函数名。
法三:
将如下两行语句放到hive的根目录的bin目录下的hive-init
add jar /home/hadoop_learn-1.0.jar;
create temporary function my_concat as 'com.ali.udf.FirstUdf';
每次连接就需要使用hive -i ./hive-init
法四:
将如下两行语句放到hive的根目录的bin目录下的.hiverc
add jar /home/hadoop_learn-1.0.jar;
create temporary function my_concat as 'com.ali.udf.FirstUdf';
每次连接就需要使用hive
法五:源码编译