Hive sql及窗口函數

hive函數:

1、根據指定條件返回結果:case when then else end as

圖1

2、基本類型轉換:CAST()

3、nvl:處理空字段:三個str時,是否為空可以指定返回不同的值

4、sql通配符:https://www.w3school.com.cn/sql/sql_wildcards.asp

5、count(1)與COUNT(*):返回行數

如果表沒有主鍵,那么count(1)比count(*)快;

如果有主鍵,那么count(主鍵,聯合主鍵)比count(*)快;

count(1)跟count(主鍵)一樣,只掃描主鍵。count(*)跟count(非主鍵)一樣,掃描整個表。明顯前者更快一些。

性能問題:

1.任何情況下SELECT COUNT(*) FROM tablename是最優(yōu)選擇,(指沒有where的情況);

2.盡量減少SELECT COUNT(*) FROM tablename WHERE COL = ‘value’ 這種查詢;

3.杜絕SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出現。

count(expression):查詢 is_reply=0 的數量: SELECT COUNT(IF(is_reply=0,1,NULL)) count FROM t_iov_help_feedback;

6、distinct與group by

distinct去重所有distinct之后所有的字段,如果有一個字段值不一致就不作為一條

group by是根據某一字段分組,然后查詢出該條數據的所需字段,可以搭配 where max(time)或者Row_Number函數使用,求出最大的一條數據

7、使用with 臨時表名 as() 的形式,簡單的臨時表直接嵌套進sql中,復雜的和需要復用的表寫到臨時表中,關聯的時候先找到關聯字段,過濾條件最好在臨時表中先過濾后關聯

處理json的函數:

split(json_array_string(schools), '\\|\\|') AS schools

get_json_object(school, '$.id') AS school_id,

字符串函數:

1、instr(’源字符串’ , ‘目標字符串’ ,’開始位置’,’第幾次出現’)

instr(sourceString,destString,start,appearPosition)

1.sourceString代表源字符串; destString代表要從源字符串中查找的子串;

2.start代表查找的開始位置,這個參數可選的,默認為1;

3.appearPosition代表想從源字符中查找出第幾次出現的destString,這個參數也是可選的, 默認為1

4.如果start的值為負數,則代表從右往左進行查找,但是位置數據仍然從左向右計算。

5.返回值為:查找到的字符串的位置。如果沒有查找到,返回0。

最簡單例子: 在abcd中查找a的位置,從第一個字母開始查,查找第一次出現時的位置

select instr(‘abcd’,’a’,1,1) from dual; —1

應用于模糊查詢:instr(字段名/列名, ‘查找字段’)

select code,name,dept,occupation from staff where instr(code, ‘001’)> 0;

等同于 select code, name, dept, occupation from staff where code like ‘%001%’ ;

應用于判斷包含關系:

select ccn,mas_loc from mas_loc where instr(‘FH,FHH,FHM’,ccn)>0;

等同于 select ccn,mas_loc from mas_loc where ccn in (‘FH’,’FHH’,’FHM’);

2、substr(string A,int start,int len)和 substring(string A,int start,int len),用法一樣

substr(time,1,8) 表示將time從第1位開始截取,截取的長度為8位

第一種用法:

substr(string A,int start)和 substring(string A,int start),用法一樣

功效:返回字符串A從下標start位置到結尾的字符串

第二種用法:

substr(string A,int start,int len)和 substring(string A,int start,int len),用法一樣

功效:返回字符串A從下標start位置開始,長度為len的字符串

3、get_json_object(form_data,'$.學生姓名') as student_name

json_tuple 函數的作用:用來解析json字符串中的多個字段

圖2

4、split(full_name, '\\.') [5] AS zq;? 取的是數組里的第六個

日期(時間)函數:

1、to_date(event_time) 返回日期部分

2、date_sub:返回當前日期的相對時間

當前日期:select curdate()?

當前日期前一天:select??date_sub(curdate(),interval 1 day)

當前日期后一天:select?date_sub(curdate(),interval -1 day)

date_sub(from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss'), 14)? 將現在的時間總秒數轉為標準格式時間,返回14天之前的時間

時間戳>>>>日期:

from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss') 將現在的時間總秒數轉為標準格式時間

from_unixtime(get_json_object(get_json_object(form_data,'$.挽單時間'),'$.$date')/1000) as retain_time

unix_timestamp('2019-08-15 16:40:00','yyyy-MM-dd HH:mm:ss')? --1565858400

日期>>>>時間戳:unix_timestamp()

date_format:yyyy-MM-dd HH:mm:ss 時間轉格式化時間

select date_format('2019-10-07 13:24:20', 'yyyyMMdd000000')-- 20191007000000select date_format('2019-10-07', 'yyyyMMdd000000')-- 20191007000000

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

3、trunc()函數的用法:當前日期的各種第一天,或者對數字進行不四舍五入的截取

日期:

1.select trunc(sysdate) from dual??--2011-3-18? 今天的日期為2011-3-18

2.select trunc(sysdate, 'mm')?? from?? dual??--2011-3-1??? 返回當月第一天.

上月1號? ? trunc(add_months(current_date(),-1),'MM')

3.select trunc(sysdate,'yy') from dual? --2011-1-1?????? 返回當年第一天

4.select trunc(sysdate,'dd') from dual? --2011-3-18??? 返回當前年月日

5.select trunc(sysdate,'yyyy') from dual? --2011-1-1?? 返回當年第一天

6.select trunc(sysdate,'d') from dual? --2011-3-13 (星期天)返回當前星期的第一天

7.select trunc(sysdate, 'hh') from dual?? --2011-3-18 14:00:00?? 當前時間為14:41??

8.select trunc(sysdate, 'mi') from dual??--2011-3-18 14:41:00?? TRUNC()函數沒有秒的精確

數字:TRUNC(number,num_digits) Number 需要截尾取整的數字。Num_digits 的默認值為 0。TRUNC()函數截取時不進行四舍五入

11.select trunc(123.458,1) from dual?--123.4

12.select trunc(123.458,-1) from dual?--120

4、round():四舍五入:

select round(1.455, 2)? #結果是:1.46,即四舍五入到十分位,也就是保留兩位小數

select round(1.5)? #默認四舍五入到個位,結果是:2

select round(255, -1)? #結果是:260,即四舍五入到十位,此時個位是5會進位

floor():地板數

ceil()天花板數

5、

6.日期轉年函數: year語法:?? year(string date)?

返回值: int

說明: 返回日期中的年。

舉例:

hive>?? select year('2011-12-08 10:03:01') from dual;

2011

hive>?? select year('2012-12-08') fromdual;

2012

7.日期轉月函數:?month語法: month?? (string date)?

返回值: int

說明: 返回日期中的月份。

舉例:

hive>?? select month('2011-12-08 10:03:01') from dual;

12

hive>?? select month('2011-08-08') fromdual;

8

8.日期轉天函數:?day語法: day?? (string date)?

返回值: int

說明: 返回日期中的天。

舉例:

hive>?? select day('2011-12-08 10:03:01') from dual;

8

hive>?? select day('2011-12-24') fromdual;

24

9.日期轉小時函數:?hour語法: hour?? (string date)?

返回值: int

說明: 返回日期中的小時。

舉例:

hive>?? select hour('2011-12-08 10:03:01') from dual;

10

10.日期轉分鐘函數:?minute語法: minute?? (string date)?

返回值: int

說明: 返回日期中的分鐘。

舉例:

hive>?? select minute('2011-12-08 10:03:01') from dual;

3

11.日期轉秒函數:?second語法: second?? (string date)?

返回值: int

說明: 返回日期中的秒。

舉例:

hive>?? select second('2011-12-08 10:03:01') from dual;

1

12.日期轉周函數:?weekofyear語法:?? weekofyear (string date)?

返回值: int

說明: 返回日期在當前的周數。

舉例:

hive>?? select weekofyear('2011-12-08 10:03:01') from dual;

49

查看hive表在hdfs中的位置:show create table 表名;

在hive中hive2hive,hive2hdfs:

HDFS、本地、hive -----> Hive:使用 insert into | overwrite、loaddata local inpath "" into table student;

Hive ----> Hdfs、本地:使用:insert overwrite | local

網站訪問量統計:

uv:每用戶訪問次數

ip:每ip(可能很多人)訪問次數

PV:是指頁面的瀏覽次數

VV:是指你訪問網站的次數

sql:

圖3

基本函數:

count、max、min、sum、avg、like、rlike('2%'、'_2%'、%2%'、'[2]')(java正則)

and、or、not、in? ?

where、group by、having、{ join on 、full join}? 、order by(desc降序)

圖4

sort by需要與distribut by集合結合使用:

hive (default)> set mapreduce.job.reduces=3;? //先設置reduce的數量?

insert overwrite local directory '/opt/module/datas/distribute-by'

row format delimited fields terminated by '\t'

先按照部門編號分區(qū),再按照員工編號降序排序。

select * from emp distribute by deptno sort by empno?desc;

外部表? create external table if not exists dept

分區(qū)表:create table dept_partition ( deptno int, dname string, loc string )? partitioned by ( month string )

load data?local inpath '/opt/module/datas/dept.txt' into table?default.dept_partition?partition(month='201809');?

?alter table dept_partition add/drop partition(month='201805') ,partition(month='201804');

多分區(qū)聯合查詢:union

select * from dept_partition2 where month='201809' and day='10';

show partitions dept_partition;

desc formatted dept_partition;

二級分區(qū)表:create table dept_partition2 ( deptno int, dname string, loc string?)?partitioned by (month string, day string)?row format delimited fields terminated by '\t';

分桶抽樣查詢:分區(qū)針對的是數據的存儲路徑;分桶針對的是數據文件

create table?stu_buck(id int, name string) clustered by(id) into 4 bucketsrow format delimited fields terminated by '\t';

設置開啟分桶與reduce為1:

set hive.enforce.bucketing=true;

set mapreduce.job.reduces=-1;

分桶抽樣:select * from stu_bucktablesample(bucket x out of y on id);

抽取,桶數/y,x是從哪個桶開始抽取,y越大 抽樣數越少,y與抽樣數成反比,x必須小于y

給空字段賦值:

如果員工的comm為NULL,則用-1代替或用其他字段代替? :select nvl(comm,-1) from emp;

case when:如何符合記為1,用于統計、分組統計

select dept_id, sum(case?sex when '男' then 1 else 0 end) man?,?sum(case sex when '女' then 1 else 0 end) woman from emp_sex?group by dept_id;

用于組合歸類匯總(行轉列):UDAF:多轉一

concat:拼接查詢結果

collect_set(col):去重匯總,產生array類型字段,類似于distinct

select t.base,?concat_ws('|',collect_set(t.name))???from (select concat_ws(',',xingzuo,blood_type) base,name ?from person_info) t?group by t.base;

解釋:先第一次查詢得到一張沒有按照(星座血型)分組的表,然后分組,使用collect_set將名字組合成數組,然后使用concat將數組變成字符串

用于拆分數據:(列轉行):UDTF:一轉多

explode(col):將hive一列中復雜的array或者map結構拆分成多行。

lateral view??側面顯示:用于和UDTF一對多函數搭配使用

用法:lateral view?udtf(expression) tablealias as cate

cate:炸開之后的列別名

temptable :臨時表表名

解釋:用于和split, explode等UDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分后的數據進行聚合。

開窗函數:

Row_Number,Rank,Dense_Rank? over:針對統計查詢使用

圖5

Row_Number:返回從1開始的序列

Rank:生成分組中的排名序號,會在名詞s中留下空位。3 3 5

dense_rank:生成分組中的排名序號,不會在名詞中留下空位。3 3 4

over:主要是分組排序,搭配窗口函數使用

結果:

圖6

SUM、AVG、MIN、MAX、count

preceding:往前

following:往后

current row:當前行

unbounded:unbounded preceding 從前面的起點, unbounded following:到后面的終點

sum:直接使用sum是總的求和,結合over使用可統計至每一行的結果、總的結果、當前行+之前多少行/之后多少行、當前行到往后所有行的求和。

over(rowsbetween 3/current rowprecedingandunboundedfollowing )? 當前行到往后所有行的求和

ntile:分片,結合over使用,可以給數據分片,返回分片號

使用場景:統計出排名前百分之或n分之一的數據。

lead,lag,FIRST_VALUE,LAST_VALUE

lag與lead函數可以返回上下行的數據

lead(col,n,dafault) 用于統計窗口內往下第n行值

第一個參數為列名,第二個參數為往下第n行(可選,默認為1),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)

LAG(col,n,DEFAULT) 用于統計窗口內往上第n行值

第一個參數為列名,第二個參數為往上第n行(可選,默認為1),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)

使用場景:通常用于統計某用戶在某個網頁上的停留時間

FIRST_VALUE:取分組內排序后,截止到當前行,第一個值

LAST_VALUE:取分組內排序后,截止到當前行,最后一個值

范圍內求和: https://blog.csdn.net/happyrocking/article/details/105369558

cume_dist,percent_rank

–CUME_DIST :小于等于當前值的 行數 / 分組內總行數

–比如,統計小于等于當前薪水的人數,占總人數的比例

percent_rank:分組內當前行的RANK值-1/分組內總行數-1

總結:

在Spark中使用spark sql與hql一致,也可以直接使用sparkAPI實現。

HiveSql窗口函數主要應用于求TopN,分組排序TopN、TopN求和,前多少名前百分之幾。

與Flink窗口函數不同。

Flink中的窗口是用于將無線數據流切分為有限塊處理的手段。

window分類:

CountWindow:按照指定的數據條數生成一個 Window,與時間無關。

TimeWindow:按照時間生成 Window。

1. 滾動窗口(Tumbling Windows):時間對齊,窗口長度固定,不重疊::常用于時間段內的聚合計算

2.滑動窗口(Sliding Windows):時間對齊,窗口長度固定,可以有重疊::適用于一段時間內的統計(某接口最近 5min 的失敗率來報警)

3.?會話窗口(Session Windows)無時間對齊,無長度,不重疊::設置session間隔,超過時間間隔則窗口關閉。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容