Hadoop學習(6)——Hive SQL(3)高級用法

一、Hive分區

 (1)Hive 分區partition:必須在表定義時指定對應的partition字段

a、單分區建表語句:
create table day_table (id int, content string) partitioned by (dt string);
單分區表,按天分區,在表結構中存在id,content,dt三列。
以dt爲文件夾區分

b、 雙分區建表語句:
create table day_hour_table (id int, content string) partitioned by (dt string, hour string);
雙分區表,按天和小時分區,在表結構中新增加了dt和hour兩列。
先以dt爲文件夾,再以hour子文件夾區分

(2)Hive添加分區表語法(表已創建,在此基礎上添加分區)

ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec  [LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;

partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)
例:
ALTER TABLE day_table ADD PARTITION (dt='2008-08-08', hour='08')

(3)Hive刪除分區語法

ALTER TABLE table_name DROP partition_spec, partition_spec,...
partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)

用戶可以用 ALTER TABLE DROP PARTITION 來刪除分區。
內部表中、對應分區的元數據和數據將被一併刪除。

例:
ALTER TABLE day_hour_table DROP PARTITION (dt='2008-08-08', hour='09');

(4)Hive向指定分區添加數據語法

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] 

例:
LOAD DATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08- 08', hour='08'); 
LOAD DATA local INPATH '/user/hua/*' INTO TABLE day_hour partition(dt='2010-07- 07');

當數據被加載至表中時,不會對數據進行任何轉換。Load操作只是將數據複製至Hive表對應的位置。數據加載時在表下自動創建一個目錄

(5)Hive查詢執行分區語法 

SELECT day_table.* FROM day_table WHERE day_table.dt>= '2008-08-08'; 
分區表的意義在於優化查詢。查詢時儘量利用分區字段。如果不使用分區字段,就會全部掃描。

Hive查詢表的分區信息語法:
SHOW PARTITIONS day_hour_table; 

預先導入分區數據,但是無法識別怎麼辦
Msck repair table tablename
直接添加分區

二、Hive SerDe

 (1)作用

SerDe 用於做序列化和反序列化,構建在數據存儲和執行引擎之間,對兩者實現解耦,Hive通過ROW   FORMAT   DELIMITED以及SERDE進行內容的讀寫

row_format
: DELIMITED 
          [FIELDS TERMINATED BY char [ESCAPED BY char]] 
          [COLLECTION ITEMS TERMINATED BY char] 
          [MAP KEYS TERMINATED BY char] 
          [LINES TERMINATED BY char] 
: SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

(2)Hive正則匹配

 CREATE TABLE logtbl (
    host STRING,
    identity STRING,
    t_user STRING,
    time STRING,
    request STRING,
    referer STRING,
    agent STRING)
  ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
  WITH SERDEPROPERTIES (
    "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
  )
  STORED AS TEXTFILE;

三、Hive Beeline 

(1)作用

Beeline 要與HiveServer2配合使用

服務端啓動hiveserver2

客戶的通過beeline兩種方式連接到hive:

1、beeline -u jdbc:hive2://localhost:10000/default -n root
2、beeline
beeline> !connect jdbc:hive2://<host>:<port>/<db>;auth=noSasl root 123

默認 用戶名、密碼不驗證

四、Hive JDBC

 (1)Hive JDBC運行方式

服務端啓動hiveserver2後,在java代碼中通過調用hivejdbc訪問默認端口10000進行連接、訪問

(2)代碼

五、常用函數

(1)關係運算符

(1)A LIKE B	字符串	如 果A或B值爲”NULL”,結果返回”NULL”。字符串A與B通過sql進行匹配,如果相符返回TRUE,不符返回FALSE。B字符串中 的”_”代表任一字符,”%”則代表多個任意字符。例如: (‘foobar’ like ‘foo’)返回FALSE,( ‘foobar’ like ‘foo_ _ _’或者 ‘foobar’ like ‘foo%’)則返回TURE
(2)A RLIKE B	字符串	如 果A或B值爲”NULL”,結果返回”NULL”。字符串A與B通過java進行匹配,如果相符返回TRUE,不符返回FALSE。例如:( ‘foobar’ rlike ‘foo’)返回FALSE,(’foobar’ rlike ‘^f.*r$’ )返回TRUE。
(3)A REGEXP B	字符串	與RLIKE相同。

(2) 算術運算符

(1)A & B	所有數字類型	運算符查看兩個參數的二進制表示法的值,並執行按位”與”操作。兩個表達式的一位均爲1時,則結果的該位爲 1。否則,結果的該位爲 0。
A|B	所有數字類型 	運算符查看兩個參數的二進制表示法的值,並執行按位”或”操作。只要任一表達式的一位爲 1,則結果的該位爲 1。否則,結果的該位爲 0。 
(2)A ^ B	所有數字類型	運算符查看兩個參數的二進制表示法的值,並執行按位”異或”操作。當且僅當只有一個表達式的某位上爲 1 時,結果的該位才爲 1。否則結果的該位爲 0。
(3)~A	所有數字類型	對一個表達式執行按位”非”(取反)。

(3)複雜類型函數

(1)map	(key1, value1, key2, value2, …)	通過指定的鍵/值對,創建一個map。
(2)struct	(val1, val2, val3, …)	通過指定的字段值,創建一個結構。結構字段名稱將COL1,COL2,…
(3)array	(val1, val2, …)	通過指定的元素,創建一個數組。

 對複雜類型函數操作:

函數

類型

說明

A[n]

A是一個數組,n爲int型

返回數組A的第n個元素,第一個元素的索引爲0。如果A數組爲['foo','bar'],則A[0]返回’foo’和A[1]返回”bar”。

M[key]

M是Map<K, V>,關鍵K型

返回關鍵值對應的值,例如mapM爲 \{‘f’ -> ‘foo’, ‘b’ -> ‘bar’, ‘all’ -> ‘foobar’\},則M['all'] 返回’foobar’。

S.x

S爲struct

返回結構x字符串在結構S中的存儲位置。如 foobar \{int foo, int bar\} foobar.foo的領域中存儲的整數。

(4)收集函數

返回類型

函數

說明

int

size(Map<K.V>)

返回的map類型的元素的數量

int

size(Array<T>)

返回數組類型的元素數量

(5)類型轉換函數

返回類型

函數

說明

指定 “type”

cast(expr as <type>)

類型轉換。例如將字符”1″轉換爲整數:cast(’1′ as bigint),如果轉換失敗返回NULL。

(6)數學函數

返回類型

函數

說明

BIGINT

round(double a)

四捨五入

DOUBLE

round(double a, int d)

小數部分d位之後數字四捨五入,例如round(21.263,2),返回21.26

BIGINT

floor(double a)

對給定數據進行向下舍入最接近的整數。例如floor(21.2),返回21。

BIGINT

ceil(double a), ceiling(double a)

將參數向上舍入爲最接近的整數。例如ceil(21.2),返回23.

double

rand(), rand(int seed)

返回大於或等於0且小於1的平均分佈隨機數(依重新計算而變)

double

exp(double a)

返回e的n次方

double

ln(double a)

返回給定數值的自然對數

double

log10(double a)

返回給定數值的以10爲底自然對數

double

log2(double a)

返回給定數值的以2爲底自然對數

double

log(double base, double a)

返回給定底數及指數返回自然對數

double

pow(double a, double p) power(double a, double p)

返回某數的乘冪

double

sqrt(double a)

返回數值的平方根

string

bin(BIGINT a)

返回二進制格式

string

hex(BIGINT a) hex(string a)

將整數或字符轉換爲十六進制格式

string

unhex(string a)

十六進制字符轉換由數字表示的字符。

string

conv(BIGINT num, int from_base, int to_base)

將 指定數值,由原來的度量體系轉換爲指定的試題體系。例如CONV(‘a’,16,2),返回。參考:’1010′ http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_conv

double

abs(double a)

取絕對值

int double

pmod(int a, int b) pmod(double a, double b)

返回a除b的餘數的絕對值

double

sin(double a)

返回給定角度的正弦值

double

asin(double a)

返回x的反正弦,即是X。如果X是在-1到1的正弦值,返回NULL。

double

cos(double a)

返回餘弦

double

acos(double a)

返回X的反餘弦,即餘弦是X,,如果-1<= A <= 1,否則返回null.

int double

positive(int a) positive(double a)

返回A的值,例如positive(2),返回2。

int double

negative(int a) negative(double a)

返回A的相反數,例如negative(2),返回-2。

 (7)日期函數

返回類型

函數

說明

string

from_unixtime(bigint unixtime[, string format])

UNIX_TIMESTAMP參數表示返回一個值’YYYY- MM – DD HH:MM:SS’或YYYYMMDDHHMMSS.uuuuuu格式,這取決於是否是在一個字符串或數字語境中使用的功能。該值表示在當前的時區。

bigint

unix_timestamp()

如果不帶參數的調用,返回一個Unix時間戳(從’1970- 01 – 0100:00:00′到現在的UTC秒數)爲無符號整數。

bigint

unix_timestamp(string date)

指定日期參數調用UNIX_TIMESTAMP(),它返回參數值’1970- 01 – 0100:00:00′到指定日期的秒數。

bigint

unix_timestamp(string date, string pattern)

指定時間輸入格式,返回到1970年秒數:unix_timestamp(’2009-03-20′, ‘yyyy-MM-dd’) = 1237532400

string

to_date(string timestamp)

返回時間中的年月日: to_date(“1970-01-01 00:00:00″) = “1970-01-01″

string

to_dates(string date)

給定一個日期date,返回一個天數(0年以來的天數)

int

year(string date)

返回指定時間的年份,範圍在1000到9999,或爲”零”日期的0。

int

month(string date)

返回指定時間的月份,範圍爲1至12月,或0一個月的一部分,如’0000-00-00′或’2008-00-00′的日期。

int

day(string date) dayofmonth(date)

返回指定時間的日期

int

hour(string date)

返回指定時間的小時,範圍爲0到23。

int

minute(string date)

返回指定時間的分鐘,範圍爲0到59。

int

second(string date)

返回指定時間的秒,範圍爲0到59。

int

weekofyear(string date)

返回指定日期所在一年中的星期號,範圍爲0到53。

int

datediff(string enddate, string startdate)

兩個時間參數的日期之差。

int

date_add(string startdate, int days)

給定時間,在此基礎上加上指定的時間段。

int

date_sub(string startdate, int days)

給定時間,在此基礎上減去指定的時間段。

(8) 條件函數

返回類型

函數

說明

T

if(boolean testCondition, T valueTrue, T valueFalseOrNull)

判斷是否滿足條件,如果滿足返回一個值,如果不滿足則返回另一個值。

T

COALESCE(T v1, T v2, …)

返回一組數據中,第一個不爲NULL的值,如果均爲NULL,返回NULL。

T

CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END

當a=b時,返回c;當a=d時,返回e,否則返回f。

T

CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END

當值爲a時返回b,當值爲c時返回d。否則返回e。

(9)字符函數

 

返回類型

函數

說明

int

length(string A)

返回字符串的長度

string

reverse(string A)

返回倒序字符串

string

concat(string A, string B…)

連接多個字符串,合併爲一個字符串,可以接受任意數量的輸入字符串

string

concat_ws(string SEP, string A, string B…)

鏈接多個字符串,字符串之間以指定的分隔符分開。

string

substr(string A, int start) substring(string A, int start)

從文本字符串中指定的起始位置後的字符。

string

substr(string A, int start, int len) substring(string A, int start, int len)

從文本字符串中指定的位置指定長度的字符。

string

upper(string A) ucase(string A)

將文本字符串轉換成字母全部大寫形式

string

lower(string A) lcase(string A)

將文本字符串轉換成字母全部小寫形式

string

trim(string A)

刪除字符串兩端的空格,字符之間的空格保留

string

ltrim(string A)

刪除字符串左邊的空格,其他的空格保留

string

rtrim(string A)

刪除字符串右邊的空格,其他的空格保留

string

regexp_replace(string A, string B, string C)

字符串A中的B字符被C字符替代

string

regexp_extract(string subject, string pattern, int index)

通過下標返回正則表達式指定的部分。regexp_extract(‘foothebar’, ‘foo(.*?)(bar)’, 2) returns ‘bar.’

string

parse_url(string urlString, string partToExtract [, string keyToExtract])

返回URL指定的部分。parse_url(‘http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1′, ‘HOST’) 返回:’facebook.com’

string

get_json_object(string json_string, string path)

select a.timestamp, get_json_object(a.appevents, ‘$.eventid’), get_json_object(a.appenvets, ‘$.eventname’) from log a;

string

space(int n)

返回指定數量的空格

string

repeat(string str, int n)

重複N次字符串

int

ascii(string str)

返回字符串中首字符的數字值

string

lpad(string str, int len, string pad)

返回指定長度的字符串,給定字符串長度小於指定長度時,由指定字符從左側填補。

string

rpad(string str, int len, string pad)

返回指定長度的字符串,給定字符串長度小於指定長度時,由指定字符從右側填補。

array

split(string str, string pat)

將字符串轉換爲數組。

int

find_in_set(string str, string strList)

返回字符串str第一次在strlist出現的位置。如果任一參數爲NULL,返回NULL;如果第一個參數包含逗號,返回0。

array<array<string>>

sentences(string str, string lang, string locale)

將字符串中內容按語句分組,每個單詞間以逗號分隔,最後返回數組。 例如sentences(‘Hello there! How are you?’) 返回:( (“Hello”, “there”), (“How”, “are”, “you”) )

array<struct<string,double>>

ngrams(array<array<string>>, int N, int K, int pf)

SELECT ngrams(sentences(lower(tweet)), 2, 100 [, 1000]) FROM twitter;

array<struct<string,double>>

context_ngrams(array<array<string>>, array<string>, int K, int pf)

SELECT context_ngrams(sentences(lower(tweet)), array(null,null), 100, [, 1000]) FROM twitter;

(10)內置的聚合函數(UDAF) 

返回類型

函數

說明

bigint

count(*) , count(expr), count(DISTINCT expr[, expr_., expr_.])

返回記錄條數。

double

sum(col), sum(DISTINCT col)

求和

double

avg(col), avg(DISTINCT col)

求平均值

double

min(col)

返回指定列中最小值

double

max(col)

返回指定列中最大值

double

var_pop(col)

返回指定列的方差

double

var_samp(col)

返回指定列的樣本方差

double

stddev_pop(col)

返回指定列的偏差

double

stddev_samp(col)

返回指定列的樣本偏差

double

covar_pop(col1, col2)

兩列數值協方差

double

covar_samp(col1, col2)

兩列數值樣本協方差

double

corr(col1, col2)

返回兩列數值的相關係數

double

percentile(col, p)

返回數值區域的百分比數值點。0<=P<=1,否則返回NULL,不支持浮點型數值。

array<double>

percentile(col, array(p~1,,\ [, p,,2,,]…))

返回數值區域的一組百分比值分別對應的數值點。0<=P<=1,否則返回NULL,不支持浮點型數值。

(11)內置表生成函數(UDTF)

返回類型

函數

說明

數組

explode(array<TYPE> a)

數組一條記錄中有多個參數,將參數拆分,每個參數生成一列。

 

json_tuple

get_json_object 語句:select a.timestamp, get_json_object(a.appevents, ‘$.eventid’), get_json_object(a.appenvets, ‘$.eventname’) from log a; json_tuple語句: select a.timestamp, b.* from log a lateral view json_tuple(a.appevent, ‘eventid’, ‘eventname’) b as f1, f2

(12)自定義函數

自定義函數包括三種UDF、UDAF、UDTF

  • UDF(User-Defined-Function) 一進一出
  • UDAF(User- Defined Aggregation Funcation) 聚集函數,多進一出。Count/max/min
  • UDTF(User-Defined Table-Generating Functions)&#160; 一進多出,如lateral view explore()

使用方式 :在HIVE會話中add 自定義函數的jar文件,然後創建function繼而使用函數

 (13)常用函數

    trim() # 去除兩邊空格
  lower(), upper() # 大小寫轉換
    cast(expr as type) # 類型轉換

    length() # 返回字符串長度
  reverse() # 反轉字符
  substring(string A, int start, int len) # 字符串截取
    concat(string A, string B, string C, ...) # 字符串連接
  concat_ws(string sep, string A, string B, string C, ...) # 自定義分隔符sep的字符串連接
  str_to_map(string A, string item_pat, string dict_pat) # 將字符串轉爲map
  
    split(string str, string pat) # 按照pat字符串分割str,返回分割後的字符串數組
  coalesce(v1, v2, v3, ...) # 返回列表中第一個非空元素,如果所有值都爲空,則返回null
  from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss') # 返回當前時間
  instr(string str, string search_str) # 返回第二個參數在待查找字符串中的位置(找不到返回0)
  map_keys(map m) # 提取出map的key, 返回key的array
  datediff(date1, date2) # 日期比較函數,返回相差天數,datediff('${cur_date},d)
  explode(colname) # explode就是將hive一行中複雜的array或者map結構拆分成多行

六、UDF 開發

 

1、UDF函數可以直接應用於select語句,對查詢結構做格式化處理後,再輸出內容。

2、編寫UDF函數的時候需要注意一下幾點:

  • 自定義UDF需要繼承org.apache.hadoop.hive.ql.UDF。
  • 需要實現evaluate函數,evaluate函數支持重載。

3、步驟

  • 把程序打包放到目標機器上去;
  • 進入hive客戶端,添加jar包:hive>add jar /run/jar/udf_test.jar;
  • 創建臨時函數:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';
  • 查詢HQL語句:

    SELECT add_example(8, 9) FROM scores;

    SELECT add_example(scores.math, scores.art) FROM scores;

    SELECT add_example(6, 7, 8, 6.8) FROM scores;

  • 銷燬臨時函數:hive> DROP TEMPORARY FUNCTION add_example;

七、UDAF 自定義集函數

多行進一行出,如sum()min(),用在group  by

1.必須繼承

org.apache.hadoop.hive.ql.exec.UDAF(函數類繼承)
org.apache.hadoop.hive.ql.exec.UDAFEvaluator(內部類Evaluator實現UDAFEvaluator接口)

2.Evaluator需要實現 inititerateterminatePartialmergeterminate這幾個函數

init():類似於構造函數,用於UDAF的初始化
iterate():接收傳入的參數,並進行內部的輪轉,返回boolean
terminatePartial():無參數,其爲iterate函數輪轉結束後,返回輪轉數據,類似於hadoop的Combiner
merge():接收terminatePartial的返回結果,進行數據merge操作,其返回類型爲boolean
terminate():返回最終的聚集函數結果

開發一個功能同:

  • Oraclewm_concat()函數
  • Mysqlgroup_concat()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章