hive基础语法三

hive基础语法三

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的数据类型。

struct

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<string,array<string>>
)
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
;

groupby

分组的意思,使用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
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

数据立方,
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的方式实现,那就是写得更复杂,大家可以尝试写一写。

rollup

卷起的意思,俗称层级聚合,相对于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<binary>,
 hivemap map<string,int>) 
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

法五:源码编译
发布了44 篇原创文章 · 获赞 7 · 访问量 2159

猜你喜欢

转载自blog.csdn.net/weixin_44273391/article/details/101066287