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 篇原創文章 · 獲贊 6 · 訪問量 2034
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章