Hive基礎學習
目錄
1.Hive基本概念
1.1 Hive簡介
1.1.1 什麼是Hive
Hive是基於Hadoop的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供類SQL查詢功能。
1.1.2 為什麼使用Hive
- 直接使用hadoop所面臨的問題
人員學習成本太高
專案週期要求太短
MapReduce實現複雜查詢邏輯開發難度太大
- 為什麼要使用Hive
操作介面採用類SQL語法,提供快速開發的能力。
避免了去寫MapReduce, 減少開發人員的學習成本。
擴充套件功能很方便。
1.1.3 Hive特點
- 可擴充套件
Hive可以自由的擴充套件叢集的規模,一般情況下不需要重啟服務。
- 延展性
Hive支援使用者自定義函式,使用者可以根據自己的需求來實現自己的函式。
- 容錯
良好的容錯性,節點出現問題SQL仍可完成執行。
2.Hive架構
2.1 架構圖
Jobtracker是hadoop1.x中的元件,它的功能相當於: Resourcemanager+AppMaster
TaskTracker 相當於: Nodemanager + yarnchild
2.2 基本組成
- 使用者介面:包括 CLI、JDBC/ODBC、WebGUI。
- 元資料儲存:通常是儲存在關係資料庫如 mysql , derby中。
- 直譯器、編譯器、優化器、執行器。
2.3 各元件的基本功能
- 使用者介面主要由三個:CLI、JDBC/ODBC和WebGUI。其中,CLI為shell命令列;JDBC/ODBC是Hive的JAVA實現,與傳統資料庫JDBC類似;WebGUI是通過瀏覽器訪問Hive。
- 名字,表的列和分割槽及其屬性,表的屬性(是否為外部表等),表的資料所在目錄等。
- 直譯器、編譯器、優化器完成 HQL 查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃的生成。生成的查詢計劃儲存在 HDFS 中,並在隨後有 MapReduce 呼叫執行。元資料儲存:Hive 將元資料儲存在資料庫中。Hive 中的元資料包括表的
2.4 Hive與Hadoop的關係
Hive利用HDFS儲存資料,利用MapReduce查詢資料
2.5 Hive與傳統資料庫的對比
總結:hive具有sql資料庫的外表,但應用場景完全不同,hive只適合用來做批量資料統計分析
2.6 Hive的資料儲存
1、Hive中所有的資料都儲存在 HDFS 中,沒有專門的資料儲存格式(可支援Text,SequenceFile,ParquetFile,RCFILE等)
2、只需要在建立表的時候告訴 Hive 資料中的列分隔符和行分隔符,Hive 就可以解析資料。
3、Hive 中包含以下資料模型:DB、Table,External Table,Partition,Bucket。
- db:在hdfs中表現為${hive.metastore.warehouse.dir}目錄下一個資料夾
- table:在hdfs中表現所屬db目錄下一個資料夾
- external table:與table類似,不過其資料存放位置可以在任意指定路徑
- partition:在hdfs中表現為table目錄下的子目錄
- bucket:在hdfs中表現為同一個表目錄下根據hash雜湊之後的多個檔案
3.Hive安裝部署
補充:先將hadoop叢集的機器配置時間同步
yum install ntpdate -y ## 安裝時間同步客戶端
ntpdate 0.asia.pool.ntp.org ## 與網際網路時間伺服器同步
若上面的時間伺服器不可用,也可以選擇以下伺服器同步時間
time.nist.gov
time.nuri.net
0.asia.pool.ntp.org
1.asia.pool.ntp.org
2.asia.pool.ntp.org
3.asia.pool.ntp.org
3.1 安裝
單機版:
元資料庫mysql版:
3.1.1 先安裝Mysql
3.1.2 安裝Hive
- 上傳tar包
- 解壓 tar -zxvf hive-0.9.0.tar.gz -C /cloud/
- 配置Hive
hive的元資料配置 vi hive-site.xml
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property><property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property><property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property><property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
<description>password to use against metastore database</description>
</property>
</configuration>
上傳一個mysql的驅動jar包到hive的安裝目錄的lib中
配置HADOOP_HOME 和HIVE_HOME到系統環境變數中:/etc/profile
source /etc/profile
hive啟動測試
4.Hive使用方式
4.1 最基本使用方式
啟動一個hive互動shell
bin/hive
hive>
設定一些基本引數,讓hive使用起來更便捷,比如:
1.讓提示符顯示當前庫:
hive>set hive.cli.print.current.db=true;
2.顯示查詢結果時顯示欄位名稱:
hive>set hive.cli.print.header=true;
但是這樣設定只對當前會話有效,重啟hive會話後就失效,解決辦法:
在linux的當前使用者目錄中,編輯一個.hiverc檔案,將引數寫入其中:
vi .hiverc
|
4.2 啟動Hive服務使用
啟動hive的服務:
[[email protected] hive-1.2.1]# bin/hiveserver2
上述啟動,會將這個服務啟動在前臺,如果要啟動在後臺,則命令如下:
不把日誌記錄在伺服器磁碟:nohup bin/hiveserver2 1>/dev/null 2>&1 &
記錄日誌到伺服器磁碟:nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &
啟動成功後,可以在別的節點上用beeline去連線
- 方式(1)
[[email protected] hive-1.2.1]# bin/beeline 回車,進入beeline的命令介面
輸入命令連線hiveserver2
beeline> !connect jdbc:hive2://mini1:10000
(hadoop01是hiveserver2所啟動的那臺主機名,埠預設是10000)
- 方式(2)
啟動時直接連線:
bin/beeline -u jdbc:hive2://mini1:10000 -n root
接下來就可以做正常sql查詢了
4.3 指令碼化執行
大量的hive查詢任務,如果用互動式shell來進行輸入的話,顯然效率及其低下,因此,生產中更多的是使用指令碼化執行機制:
該機制的核心點是:hive可以用一次性命令的方式來執行給定的hql語句
[[email protected] ~]# hive -e "insert into table t_dest select * from t_src;"
然後,進一步,可以將上述命令寫入shell指令碼中,以便於指令碼化執行hive任務,並控制、排程眾多hive任務,示例如下:
vi t_order_etl.sh
|
如果要執行的hql語句特別複雜,那麼,可以把hql語句寫入一個檔案:
vi x.hql
|
然後,用hive -f /root/x.hql 來執行
5.Hive建庫建表與資料匯入
5.1 建庫
hive中有一個預設的庫:
庫名: default 庫目錄:hdfs://hdp20-01:9000/user/hive/warehouse
新建庫:create database db_order;
庫建好後,在hdfs中會生成一個庫目錄: hdfs://hdp20-01:9000/user/hive/warehouse/db_order.db
5.2 建表
建表語法:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
說明:
- CREATE TABLE 建立一個指定名字的表。如果相同名字的表已經存在,則丟擲異常;使用者可以用 IF NOT EXISTS 選項來忽略這個異常。
- EXTERNAL關鍵字可以讓使用者建立一個外部表,在建表的同時指定一個指向實際資料的路徑(LOCATION),Hive 建立內部表時,會將資料移動到資料倉庫指向的路徑;若建立外部表,僅記錄資料所在的路徑,不對資料的位置做任何改變。在刪除表的時候,內部表的元資料和資料會被一起刪除,而外部表只刪除元資料,不刪除資料。
- LIKE 允許使用者複製現有的表結構,但是不復制資料。
- ROW FORMAT
DELIMITED [FIELDS TERMINATED 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, ...)]
使用者在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,使用者還需要為表指定列,使用者在指定表的列的同時也會指定自定義的 SerDe,Hive通過 SerDe 確定表的具體的列的資料。
5.STORED AS
SEQUENCEFILE|TEXTFILE|RCFILE
如果檔案資料是純文字,可以使用 STORED AS TEXTFILE。如果資料需要壓縮,使用 STORED AS SEQUENCEFILE。
6、CLUSTERED BY
對於每一個表(table)或者分割槽, Hive可以進一步組織成桶,也就是說桶是更為細粒度的資料範圍劃分。Hive也是 針對某一列進行桶的組織。Hive採用對列值雜湊,然後除以桶的個數求餘的方式決定該條記錄存放在哪個桶當中。
把表(或者分割槽)組織成桶(Bucket)有兩個理由:
(1)獲得更高的查詢處理效率。桶為表加上了額外的結構,Hive 在處理有些查詢時能利用這個結構。具體而言,連線兩個在(包含連線列的)相同列上劃分了桶的表,可以使用 Map 端連線 (Map-side join)高效的實現。比如JOIN操作。對於JOIN操作兩個表有一個相同的列,如果對這兩個表都進行了桶操作。那麼將儲存相同列值的桶進行JOIN操作就可以,可以大大較少JOIN的資料量。
(2)使取樣(sampling)更高效。在處理大規模資料集時,在開發和修改查詢的階段,如果能在資料集的一小部分資料上試執行查詢,會帶來很多方便。
5.2.1 基本建表語句
use db_order;
create table t_order(id string,create_time string,amount float,uid string);
表建好後,會在所屬的庫目錄中生成一個表目錄
/user/hive/warehouse/db_order.db/t_order
只是,這樣建表的話,hive會認為表資料檔案中的欄位分隔符為 ^A(\001)
正確的建表語句為:
create table t_order(id string,create_time string,amount float,uid string)
row format delimited
fields terminated by ',';
這樣就指定了,我們的表資料檔案中的欄位分隔符為 ","
注意:hive是不會檢查使用者匯入表中的資料的!如果資料的格式跟表定義的格式不一致,hive也不會做任何處理(能解析就解析,解析不了就是null);
5.2.2 刪除表
drop table t_order;
刪除表的效果是:
hive會從元資料庫中清除關於這個表的資訊;
hive還會從hdfs中刪除這個表的表目錄;
5.2.3 內部表與外部表
內部表(MANAGED_TABLE):表目錄按照hive的規範來部署,位於hive的倉庫目錄/user/hive/warehouse中
外部表(EXTERNAL_TABLE):表目錄由建表使用者自己指定
create external table t_access(ip string,url string,access_time string)
row format delimited
fields terminated by ','
location '/access/log';
外部表和內部表的特性差別:
- 內部表的目錄在hive的倉庫目錄中 VS 外部表的目錄由使用者指定
- drop一個內部表時:hive會清除相關元資料,並刪除表資料目錄
- drop一個外部表時:hive只會清除相關元資料;
一個hive的資料倉庫,最底層的表,一定是來自於外部系統,為了不影響外部系統的工作邏輯,在hive中可建external表來對映這些外部系統產生的資料目錄;
然後,後續的etl操作,產生的各種中間表建議用managed_table(內部表)
5.2.4 分割槽表
分割槽表的實質是:在表目錄中為資料檔案建立分割槽子目錄,以便於在查詢時,MR程式可以針對指定的分割槽子目錄中的資料進行處理,縮減讀取資料的範圍,提高效率!
比如,網站每天產生的瀏覽記錄,瀏覽記錄應該建一個表來存放,但是,有時候,我們可能只需要對某一天的瀏覽記錄進行分析
這時,就可以將這個表建為分割槽表,每天的資料匯入其中的一個分割槽;
當然,每日的分割槽目錄,應該有一個目錄名(分割槽欄位)
5.2.4.1 一個分割槽欄位的例項
示例如下:
- 建立帶分割槽的表
|
注意:分割槽欄位不能是表定義中的已存在欄位
2.向分割槽中匯入資料
load data local inpath '/root/access.log.2017-08-04.log' into table t_access partition(dt='20170804');
load data local inpath '/root/access.log.2017-08-05.log' into table t_access partition(dt='20170805');
3.針對分割槽資料進行查詢
a、統計8月4號的總PV:
select count(*) from t_access where dt='20170804';
實質:就是將分割槽欄位當成表字段來用,就可以使用where子句指定分割槽了
b、統計表中所有資料總的PV:
select count(*) from t_access;
實質:不指定分割槽條件即可
5.2.4.2 多個分割槽欄位示例
建表:
create table t_partition(id int,name string,age int)
partitioned by(department string,sex string,howold int)
row format delimited fields terminated by ',';
導資料:
load data local inpath '/root/p1.dat' into table t_partition partition(department='xiangsheng',sex='male',howold=20);
5.2.5 CTAS建表語法
可以通過已存在表來建表:
1、create table t_user_2 like t_user;
新建的t_user_2表結構定義與源表t_user一致,但是沒有資料
2.在建表的同時插入資料
|
t_access_user會根據select查詢的欄位來建表,同時將查詢的結果插入新表中!
補充:將查詢出來的資料儲存到一張表中:
方式1:create t_x as select .......
方式2:
如果事先存在一張表t_x
可以將select查詢出來的結果資料insert到這張已存在的表中;
insert into t_x select .......
5.3 資料匯入匯出
5.3.1 將資料檔案匯入hive的表
方式1:匯入資料的一種方式:
手動用hdfs命令,將檔案放入表目錄;
方式2:在hive的互動式shell中用hive命令來匯入本地資料到表目錄
hive>load data local inpath '/root/order.data.2' into table t_order;
方式3:用hive命令匯入hdfs中的資料檔案到表目錄
hive>load data inpath '/access.log.2017-08-06.log' into table t_access;
注意:導本地檔案和導HDFS檔案的區別:
本地檔案匯入表:複製
hdfs檔案匯入表:移動
方式4:如果目標表是一個分割槽表
hive> load data [local] inpath ‘......’ into table t_dest partition(p=’value’);
5.3.2 將hive表中的資料匯出到指定路徑的檔案
- 將hive表中的資料匯入HDFS的檔案
insert overwrite directory '/root/access-data'
row format delimited fields terminated by ','
select * from t_access;
2.將hive表中的資料匯入本地磁碟檔案
insert overwrite local directory '/root/access-data'
row format delimited fields terminated by ','
select * from t_access limit 100000;
5.3.3 hive檔案格式
HIVE支援很多種檔案格式: SEQUENCE FILE | TEXT FILE | PARQUET FILE | RC FILE
create table t_text(movie string,rate int) stored as textfile;
create table t_seq(movie string,rate int) stored as sequencefile;
create table t_pq(movie string,rate int) stored as parquetfile;
演示:
1、先建一個儲存文字檔案的表
create table t_access_text(ip string,url string,access_time string)row format delimited fields terminated by ','
stored as textfile;
匯入文字資料到表中:
load data local inpath '/root/access-data/000000_0' into table t_access_text;
2.建一個儲存sequence file檔案的表:
create table t_access_seq(ip string,url string,access_time string)
stored as sequencefile;
從文字表中查詢資料插入sequencefile表中,生成資料檔案就是sequencefile格式的了:
insert into t_access_seq
select * from t_access_text;
3.建一個儲存parquet file檔案的表:
create table t_access_parq(ip string,url string,access_time string)
stored as parquetfile;
5.4 資料型別
5.4.1 數字型別
TINYINT (1位元組整數)
SMALLINT (2位元組整數)
INT/INTEGER (4位元組整數)
BIGINT (8位元組整數)
FLOAT (4位元組浮點數)
DOUBLE (8位元組雙精度浮點數)
示例:
create table t_test(a string ,b int,c bigint,d float,e double,f tinyint,g smallint)
5.4.2 時間型別
TIMESTAMP (時間戳) (包含年月日時分秒毫秒的一種封裝)
DATE (日期)(只包含年月日)
示例,假如有以下資料檔案:
1,zhangsan,1985-06-31 2,lisi,1986-07-10 3,wangwu,1985-08-09 |
那麼,就可以建一個表來對資料進行對映
create table t_customer(id int,name string,birthday date)
row format delimited fields terminated by ',';
然後匯入資料
load data local inpath '/root/customer.dat' into table t_customer;
然後,就可以正確查詢
5.4.3 字串型別
VARCHAR(20) (字串1-65535長度,超長截斷)
CHAR (字串,最大長度255)
5.4.4 其他型別
BOOLEAN(布林型別):true false
BINARY (二進位制):
舉例:
1,zs,28,true
2,ls,30,false
3,ww,32,false
4,lulu,18,true
create table t_p(id int,name string,age int,is_married boolean)
select
from t_p where is_married;
5.4.5 複合(集合)型別
5.4.5.1 array陣列型別
arrays: ARRAY<data_type> )
示例:array型別的應用
假如有如下資料需要用hive的表去對映:
戰狼2,吳京:吳剛:余男,2017-08-16 三生三世十里桃花,劉亦菲:癢癢,2017-08-20 羞羞的鐵拳,沈騰:瑪麗:艾倫,2017-12-20 |
設想:如果主演資訊用一個數組來對映比較方便
建表:
create table t_movie(moive_name string,actors array<string>,first_show date)
row format delimited fields terminated by ','
collection items terminated by ':';
匯入資料:
load data local inpath '/root/movie.dat' into table t_movie;
查詢:
select * from t_movie;
select moive_name,actors[0] from t_movie;
select moive_name,actors from t_movie where array_contains(actors,'吳剛');
select moive_name,size(actors) from t_movie;
5.4.5.2 map型別
maps: MAP<primitive_type, data_type>
- 假如有以下資料:
1,zhangsan,father:xiaoming#mother:xiaohuang#brother:xiaoxu,28 2,lisi,father:mayun#mother:huangyi#brother:guanyu,22 3,wangwu,father:wangjianlin#mother:ruhua#sister:jingtian,29 4,mayun,father:mayongzhen#mother:angelababy,26 |
可以用一個map型別來對上述資料中的家庭成員進行描述
- 建表語句:
create table t_person(id int,name string,family_members map<string,string>,age int)
row format delimited fields terminated by ','
collection items terminated by '#'
map keys terminated by ':';
- 查詢
select * from t_person;
## 取map欄位的指定key的值
select id,name,family_members['father'] as father from t_person;
## 取map欄位的所有key
select id,name,map_keys(family_members) as relation from t_person;
## 取map欄位的所有value
select id,name,map_values(family_members) from t_person;
select id,name,map_values(family_members)[0] from t_person;
## 綜合:查詢有brother的使用者資訊
方式1:
|
方式2:
select * from t_map where array_contains(map_keys(family),'sister');
5.4.5.3 struct型別
struct: STRUCT<col_name : data_type, ...>
- 假如有如下資料:
1,zhangsan,18:male:beijing 2,lisi,28:female:shanghai |
其中的使用者資訊包含:年齡:整數,性別:字串,地址:字串
設想用一個欄位來描述整個使用者資訊,可以採用struct
2.建表:
create table t_person_struct(id int,name string,info struct<age:int,sex:string,addr:string>)
row format delimited fields terminated by ','
collection items terminated by ':';
3.查詢
select * from t_person_struct;
select id,name,info.age from t_person_struct;
5.5 修改表定義
僅修改Hive元資料,不會觸動表中的資料,使用者需要確定實際的資料佈局符合元資料的定義。
修改表名:
ALTER TABLE table_name RENAME TO new_table_name
示例:alter table t_1 rename to t_x;
修改分割槽名:
alter table t_partition partition(department='xiangsheng',sex='male',howold=20) rename to partition(department='1',sex='1',howold=20);
新增分割槽:
alter table t_partition add partition (department='2',sex='0',howold=40);
刪除分割槽:
alter table t_partition drop partition (department='2',sex='2',howold=24);
修改表的檔案格式定義:
ALTER TABLE table_name [PARTITION partitionSpec] SET FILEFORMAT file_format
修改表的某個檔案格式定義:
alter table t_partition partition(department='2',sex='0',howold=40 ) set fileformat sequencefile;
修改列名定義:
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENTcol_comment] [FIRST|(AFTER column_name)]
alter table t_user change price jiage float first;
增加/替換列:
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type[COMMENT col_comment], ...)
alter table t_user add columns (sex string,addr string);
alter table t_user replace columns (id string,age int,price float);
6.hive查詢語法
sql是一門面向集合的程式語言;
select 1;
提示:在做小資料量查詢測試時,可以讓hive將mrjob提交給本地執行器執行,可以在hive會話中設定如下引數:
hive> set hive.exec.mode.local.auto=true;
6.1 基本查詢示例
select * from t_access;
select count(*) from t_access;
select max(ip) from t_access;
6.2 條件查詢
select * from t_access where access_time<'2017-08-06 15:30:20'
select * from t_access where access_time<'2017-08-06 16:30:20' and ip>'192.168.33.3';
6.3 join關聯查詢示例
假如有a.txt檔案
a,1 b,2 c,3 d,4 |
假如有b.txt檔案
a,xx b,yy d,zz e,pp |
進行各種join查詢:
- inner join(join)
|
結果:
+--------+--------+--------+--------+--+ | aname | anumb | bname | bnick | +--------+--------+--------+--------+--+ | a | 1 | a | xx | | b | 2 | b | yy | | d | 4 | d | zz | +--------+--------+--------+--------+--+ |
2.left outer join(left join)
|
結果:
3.right outer join(right join)
|
結果:
4.full outer join(full join)
|
結果:
6.4 left semi join
Left semi join :相當於join連線兩個表後產生的資料中的左半部分
hive中不支援exist/IN子查詢,可以用left semi join來實現同樣的效果:
|
結果:
注意: left semi join的 select子句中,不能有右表的欄位
6.5 group by 分組聚合
20170804,192.168.33.66,http://www.ed.cn/job 20180804,192.168.33.40,http://www.ed.cn/study 20180805,192.168.20.18,http://www.ed2.cn/job 20180805,192.168.20.28,http://www.ed2.cn/login 20180806,192.168.20.38,http://www.ed2.cn/job 20180806,192.168.20.38,http://www.ed2.cn/study 20180807,192.168.33.40,http://www.ed2.cn/login 20180807,192.168.20.88,http://www.ed2.cn/job |
select dt,count(*),max(ip) as cnt from t_access group by dt;
select dt,count(*),max(ip) as cnt from t_access group by dt having dt>'20170804';
select
dt,count(*),max(ip) as cnt
from t_access
where url='http://www.ed.cn/job'
group by dt having dt>'20170804';
注意: 一旦有group by子句,那麼,在select子句中就不能有 (分組欄位,聚合函式) 以外的欄位
## 為什麼where必須寫在group by的前面,為什麼group by後面的條件只能用having
因為,where是用於在真正執行查詢邏輯之前過濾資料用的
having是對group by聚合之後的結果進行再過濾;
上述語句的執行邏輯:
- where過濾不滿足條件的資料
- 用聚合函式和group by進行資料運算聚合,得到聚合結果
- 用having條件過濾掉聚合結果中不滿足條件的資料
6.6 子查詢
1,zhangsan,father:xiaoming#mother:xiaohuang#brother:xiaoxu,28 2,lisi,father:mayun#mother:huangyi#brother:guanyu,22 3,wangwu,father:wangjianlin#mother:ruhua#sister:jingtian,29 4,mayun,father:mayongzhen#mother:angelababy,26 |
-- 查詢有兄弟的人
select id,name,brother
from
(select id,name,family_members['brother'] as brother from t_person) tmp
where brother is not null;
另一種寫法:
select id,name,family_members[‘brother’]
from t_person where array_contains(map_keys(family_members),”brother”);
7.hive函式使用
測試函式小技巧:
直接用常量來測試函式即可
select substr("abcdefg",1,3);
而且,可以將hive的本地執行自動模式開啟:
hive>set hive.exec.mode.local.auto=true;
HIVE 的所有函式手冊:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-Built-inTable-GeneratingFunctions(UDTF)
7.1 常用內建函式
select cast("5" as int)
select cast("2017-08-03" as date) ;
select cast(current_timestamp as date);
7.1.1型別轉換函式
1 |
1995-05-05 13:30:59 |
1200.3 |
2 |
1994-04-05 13:30:59 |
2200 |
3 |
1996-06-01 12:20:30 |
80000.5 |
create table t_fun(id string,birthday string,salary string)
row format delimited fields terminated by ',';
select id,cast(birthday as date) as bir,cast(salary as float) from t_fun;
7.1.2 數學運算函式
select round(5.4); ## 5 四捨五入
select round(5.1345,3) ; ##5.135
select ceil(5.4) ; // select ceiling(5.4) ; ## 6 向上取整
select floor(5.4); ## 5 向下取整
select abs(-5.4) ; ## 5.4 絕對值
select greatest(id1,id2,id3) ; ## 6 單行函式
select least(3,5,6) ; ##求多個輸入引數中的最小值
示例:
有表如下:
select greatest(cast(s1 as double),cast(s2 as double),cast(s3 as double)) from t_fun2;
結果:
+---------+--+
| _c0 |
+---------+--+
| 2000.0 |
| 9800.0 |
+---------+--+
select max(age) from t_person group by ..; 分組聚合函式
select min(age) from t_person group by...; 分組聚合函式
7.1.3 字串函式
substr(string str, int start) ## 擷取子串
substring(string str, int start)
示例:select substr("abcdefg",2) ;
substr(string, int start, int len)
substring(string, int start, int len)
示例:select substr("abcdefg",2,3) ; ## bcd
concat(string A, string B...) ## 拼接字串
concat_ws(string SEP, string A, string B...)
示例:select concat("ab","xy") ; ## abxy
select concat_ws(".","192","168","33","44") ; ## 192.168.33.44
length(string A)
示例:select length("192.168.33.44"); ## 13
split(string str, string pat) ## 切分字串,返回陣列
示例:
錯誤的,因為.號是正則語法中的特定字元select split("192.168.33.44",".") ;select split("192.168.33.44","\\.") ;
upper(string str) ##轉大寫
lower(string str) ##轉小寫
7.1.4 時間函式
select current_timestamp(); ## 返回值型別:timestamp,獲取當前的時間戳(詳細時間資訊)
select current_date; ## 返回值型別:date,獲取當前的日期
## unix時間戳轉字串格式——from_unixtime
from_unixtime(bigint unixtime[, string format])
示例:select from_unixtime(unix_timestamp());
select from_unixtime(unix_timestamp(),"yyyy/MM/dd HH:mm:ss");
## 字串格式轉unix時間戳——unix_timestamp:返回值是一個長整數型別
## 如果不帶引數,取當前時間的秒數時間戳long--(距離格林威治時間1970-1-1 0:0:0秒的差距)
select unix_timestamp();
unix_timestamp(string date, string pattern)
示例: select unix_timestamp("2017-08-10 17:50:30");
select unix_timestamp("2017-08-10 17:50:30","yyyy-MM-dd HH:mm:ss");
## 將字串轉成日期date
select to_date("2017-09-17 16:58:32");
7.1.5 條件控制函式
7.1.5.1 IF
select id,if(age>25,'working','worked') from t_user;
select moive_name,if(array_contains(actors,'吳剛'),'好電影',’爛片兒’)