基礎語句
CREATE DROP
建表、刪表
- 建表
-------------------------------------- -- 1. 直接建表 -------------------------------------- -- 創建非分區表時,省去后半部分即可 create table if not exists table_name( id string comment 'id ', num string comment '數值' ) partitioned by ( ym string comment '月份 ' ); -------------------------------------- -- 2. 復制其他表的表結構 -------------------------------------- create table if not exists new_table like old_table; -------------------------------------- -- 3. 從其他表選取數據創建並插入新表 -------------------------------------- create table if not exists new_table as select * from old_table;
- 刪表
drop table table_name ;
ALTER
更改表結構
分區
- 添加分區
alter table table_name add if not exists partition (y='2016',m='12');
- 刪除分區
ALTER TABLE table_name DROP IF EXISTS PARTITION (ym='201706');
- 重命名分區
ALTER TABLE table_name PARTITION (y='2017',m='05') RENAME TO PARTITION (y='2017',m='06');
列
- 刪除列
ALTER TABLE table_name DROP COLUMN id;
- 增加列
Alter table table_name add COLUMNS (id string comment '代號');
- 修改列 (此處可用於 修改字段注釋)
ALTER TABLE table_name CHANGE id level string comment '層級代號';
- 替換列
ALTET TABLE table_name REPLACE COLUMNS
(id_new string COMMENT '新字段1', level_new string COMMENT '新字段2');
表
- 重命名表名
ALTER TABLE old_table RENAME TO new_table;
INSERT
插入
- 插入單條數據 (Hive 已支持單條插入)
insert into table_name values(201705,'lol');
- 插入分區表
insert overwrite table table_name PARTITION (y='2017',m='01') select * from table_name_2 where pt = concat('2017','01');
LOAD
載入
- 重寫載入分區表 (非分區表同理)
LOAD DATA LOCAL INPATH 'total.txt' overwrite into table table_name partition (y='2016',m='12');
其他語句
- 其他基礎SQL類似的語句不再贅述,此處再多列舉幾個常用語句:
-- 列舉庫或表 SHOW DATABASES/TABLES; -- 根據關鍵字查找庫或表 SHOW DATABASES/TABLES LIKE "*keyword*"; -- 列舉所有函數 SHOW FUNCTIONS; -- 查看分區 SHOW PARTITIONS test_table; -- 查看建表語句 SHOW CREATE TABLE table_name; -- 詳細描述,包括建表時間、最后更新時間、行數統計等。 DESC FORMATTED test_table; -- 解釋語句 EXPLAIN select * from dual; -- 清空表 truncate table table_name;
函數、技巧、方法
- 執行順序理解
根據 explain 語句的使用發現,在執行以下語句時:
在TableScan
步驟,where條件中若有分區篩選條件且目標分區確實存在、且判斷方式為=
時,自動進行過濾, 然后再在Filter Operator
進行其他條件的篩選:predicate: (latitude is not null and (UDFToDouble(longitude) > 100.0) AND (UDFToDouble(ym) > 201701.0)) (type: boolean)
predicate: (lat_avg is not null and lng_avg is not null) (type: boolean)
所以, 先join在where和先where在join是等等價的
select b.*, a.name,a.price,a.city from table_name_a a join table_name_b b on round(b.lng_avg,2) = round(a.longitude,2) and round(b.lat_avg,2) = round(a.latitude,2) where a.longitude >100
-
shell內通過
hive -v " "
調用執行HiveQL語句時,如需要注釋,請注意轉義問題- 注釋的那條語句不能含有分號
;
- 注釋語句后接語句盡量避免導jar包的語句
- 避免使用 /* */
- 注釋的那條語句不能含有分號
-
選擇除某幾個字段外的所有字段
當某個表的字段特別多,若想選取除某幾個字段外的所有字段時,這時語句寫起來就會很麻煩,比如有時兩個表join的條件的字段名相同時,只能保留一個字段。但有一個方法可以解決這個問題,如下:
set hive.support.quoted.identifiers=none; select `(y|m|d)?+.+` from dual;
- 需注意:
- 括號內不能有空格
- 在shell里調用時需要對這個反引號進行轉義
- 通過
concat_ws
、collect_set
和str_to_map
的使用,實現字符串轉map
str_to_map(concat_ws(',',collect_set(concat_ws(':',key, cast(value as string)))))
avg()
函數會自動剔除NULL,總數除以非NULL個數- 字符串截取函數
substr
、substring
是等價的
substr(string A, int start, int len)
substring(string A, int start, int len) -
x between a and b
等同於a<= x <=b
-
子查詢加最好要加別稱
報錯:Failed rule: ‘identifier’ in subquery source
解決:子查詢加 別稱 -
設置隊列問題,
mapred.job.queue.name
與mapreduce.job.queuename
set mapred.job.queue.name=queue_xx;
MRv2重新命名了MRv1中的所有配置參數,但兼容MRv1中的舊參數,只不過會打印一條警告日志提示用戶參數過期。詳見此篇博文。
- 查詢表的實際更新情況
desc formatted 的結果往往只有CreateTime
,LastAccessTime
經常為UNKNOWN
的狀態,可以用hadoop 指令去查詢數據文件的真實更新時間:hadoop fs ‐ls truePath/databaseName.db/tableName/
調優
占個坑,有時間再來填
Hive里的坑點
limit m,n
的問題
使用語句:create table a as select * from b limit m,n
時,會導致新建表a內無數據,解決辦法:
- 看似可以其實並不好使:
create table a as select * from (select * from b limit m,n ) t
- 解決: 使用
row_number()
加序號,根據序號選取
- 看似可以其實並不好使:
- NULL 值問題
length(NULL)
等於NULL
NULL
與空字符串
:
由下可見:NULL
不可以與字符串或數值比較,''
可與字符串比較但不可與數值比較
hive (xx_safe)> select * from dual; OK dual.lol 100 50 1 1 2 fangjiale NULL --(此處為'') hive (xx_safe)> select * from dual where lol !='1'; OK dual.lol fangjiale 100 50 2 --(此處為'') hive (xx_safe)> select * from dual where lol !=1; OK dual.lol 100 50 2