當前位置:首頁 » 編程語言 » hivesql方差函數
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

hivesql方差函數

發布時間: 2023-05-12 12:52:58

A. Hivesql核心技能之窗口計算

目標:
1、掌握 sum()、avg()等用於累計計算的聚合函數,學會對行數的限制(移動計算);
2、掌握 row_number(),rank()、dense_rank()用於排序的函數;
3、掌握 ntile()用於分組查詢的函數;
4、掌握 lag()、lead()偏移分析函數

窗口函數(window function):
與聚合函數類似,但是窗口函數是每一行數據都生成一個結果,聚合函數可以將多行數據按照規定聚合為一行,一般來說聚合後的行數要少於聚合前的行數,但是有時我們想要既顯示聚合前的數據,又要顯示聚合後的數據,這時便引入了窗口函數, 窗口函數是在 select 時執行的,位於 order by 之前

在日常工作中,經常遇到 計算截止某月或某天的累計數值 ,在Excel可以通過函數來實現,
在HiveSQL里,可以利用窗口函數實現。

1)2018年每月的支付總額和當年累計支付總額

2)對2017年和2018年公司的支付總額按月度累計進行分析,按年度進行匯總

說明:1、over中的 partition by 起到分組的作用;
2、order by 按照什麼順序進行累加,升序ASC、降序DESC,默認升序
3、正確的分組是非常重要的,partition by 後面的欄位是需要累計計算的區域,需要仔細理解

(計算三日留存、七日留存、三十日留存等方式可以使用這個函數。)

3)對2018年每個月的近三個月進行移動的求平均支付金額

用法:這三個函數的作用都是返回相應規則的排序序號,由於排序函數不是二次聚合計算,因此不一定要使用子查詢

4)2019年1月,用戶購買商品品類數量的排名

5)選出2019年支付金額排名在第10、20、30名的用戶

6)將2019年1月的支付用戶,按照支付金額分成5組

7)選出2019年退款金額排名前10%的用戶

說明:Lag和Lead分析函數可以在同一次查詢中取出同一欄位的 前N行數據(Lag)和後N行的數據(Lead) 作為獨立的列。

在實際應用當中,若要用到取今天和昨天的某欄位差值時,Lag和Lead函數的應用就顯得尤為重要。
當然,這種操作可以用表的 自連接實現 ,但是Lag和Lead與 left join、 right join等自連接相比,效率更高,SQL語句更簡潔。

8)支付時間間隔超過100天的用戶數(這一次購買距離下一次購買的時間?,注意datediff函數是日期大的在前面)

9)每個城市,不同性別,2018年支付金額最高的TOP3用戶

步驟總結:
1、首先篩選出每個用戶和每個用戶總的消費金額;
2、對兩個表進行連接提取需要的欄位;
3、對連接後的表進行二次聚合計算,計算出不同城市、性別的金額排名;
4、對二次聚合計算的表進行條件篩選提取

10)每個手機品牌退款金額前25%的用戶

步驟總結:
1、首先篩選出每個用戶和每個用戶的總退款金額;
2、對兩個表進行連接提取需要的欄位;
3、對連接後的表進行按手機品牌內分組;
4、對分組後的表進行條件篩選提取

B. Hive簡易教程 - 數據分析

Hive是一個HDFS上的sql執行引擎,它將sql語句轉化為Hadoop上的map-rece任務來執行。由於是寫sql,所以使用Hive進行數據分析的好處是沒有什麼額外的學習成本,但是它是批量式處理的,可能會比較慢。本文將通過幾個案例來簡單介紹如何使用Hive。

** 隨機生成一批訂單數據(order_id, price, tag, order_date) **

** 存儲數據到Hive **

** 統計出近一周每天成功支付的訂單總數,gmv,客單價 **

** 統計出近一周每天成功支付 及支付失敗 各自的訂單總數,gmv,客單價 **

count函數和if條件組合,而不是兩個sql join

** 挑選出近一周gmv>1000並且訂單量>2單的賣家ID及其訂單 **

  在使用group by之後只能select出group key以及相關的統計數字,但也可以以集合的形式select出任何其他的非group key,比如按賣家ID聚合之後又想查看在這個賣家下單的買家ID:sellect collect_set(buyer_id) from t group by seller_id。

  與collect_set類似,元素可重復

  explode函數可以把一個array類型的數據扁平化。比如,現在每行是一個seller_id集合,使用explode可以扁平化為每行一個seller_id。但explode不可以直接與group by一起使用,比如我想按某些條件篩選一些賣家然後在查看該店鋪的買家的情況:select explode(b.buyer_ids) from (select collect_set(buyer_id) as buyer_ids from t group by seller_id) b;

  當前時間

  將系統時間戳轉化為人可讀的數據格式 如:select from_unixtime(unix_timestamp(), 'yyyy-MM-dd');

  求幾天前的日期

  nvl函數用於處理null值,當一個欄位是null時,這個欄位和其它欄位進行算術運算時的結果依然為null。這時可以使用這個函數為值可能為null的欄位賦予一個默認值,即v2.

  判斷字元串'xxx'是否出現在str1中,如果str1是null或者不存在xxx返回值都是0

  返回數組a1的大小

  合並兩個查詢結果,但結果的列數需要一致!!!

C. hive窗口函數總結

根據官網的介紹,hive推出的窗口函數功能是對hive sql的功能增強,確實目前用於離線數據分析邏輯日趨復雜,很多場景都需要用到。以下就是對hive窗口函數的一個總結附上案例。

PRECEDING:往前
FOLLOWING:往後
CURRENT ROW:當前行
UNBOUNDED:起點(一般結合PRECEDING,FOLLOWING使用)
UNBOUNDED PRECEDING 表示該窗口最前面的行(起點)
UNBOUNDED FOLLOWING:表示該窗口最後面的行(終點)
比如說:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(表示從起點到當前行)
ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING(表示往前2行到往後1行)
ROWS BETWEEN 2 PRECEDING AND 1 CURRENT ROW(表示往前2行到當前行)
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING(表示當前行到終點)
官網有一段話列出了哪些窗口函數是不支持window子句的,如下圖所示:

1.LEAD(col,n,DEFAULT) 用於統計窗口內往下第n行值第一個參數為列名,第二個參數為往下第n行(可選,默認為1,不可為負數),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)

2.LAG(col,n,DEFAULT) 用於統計窗口內往上第n行值第一個參數為列名,第二個參數為往上第n行(可選,默認為1,不可為負數),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)

3.FIRST_VALUE取分組內排序局宏後,截止到當前行,第一個值,這最多需要兩個參數。第一個參數是您想要第一個值的列,第二個(可選桐信冊)參數必須是false默認為布爾值的布爾值。如果設置為true,則跳過空值。

4.LAST_VALUE取分組內排序後,截止到當前行,最後一個值,這最多需要兩個參數。第一個參數是您想要第一個值的列,第二個(可選)參數必須是false默認為布爾值的布爾值。如果設置為true,則跳過空值。

讓我們加上window子句來觀察一下變化,雖然FIRST_VALUE和LAST_VALUE不常於與window子句結合使用。

1.COUNT
2.SUM
3.MIN
4.MAX
5.AVG
目前支持這五種帶有聚合意義的窗口函數,以常用SUM舉例。

從結果當中其實可以得到結論,默認情況就是從起點到當前行,不帶order by語句其實就是表示窗口內全部行都參與聚合處理,這里其實還有其他用法,讀者坦枯可以自行嘗試一下。

1.ROW_NUMBER
從1開始,按照順序,生成分組內記錄的序列,row_number()的值不會存在重復,當排序的值相同時,按照表中記錄的順序進行排列;通常用於獲取分組內排序第一的記錄;獲取一個session中的第一條refer等。
2.RANK
生成數據項在分組中的排名,排名相等會在名次中留下空位。
3.DENSE_RANK
生成數據項在分組中的排名,排名相等會在名次中不會留下空位。
4.CUME_DIST
CUME_DIST 小於等於當前值的行數/分組內總行數
5.PERCENT_RANK
PERCENT_RANK 分組內當前行的RANK值-1/分組內總行數-1
6.NTILE
NTILE(n) 用於將分組數據按照順序切分成n片,返回當前切片值,如果切片不均勻,默認增加第一個切片的分布。NTILE不支持ROWS BETWEEN
以上是帶有分析功能的窗口函數,使用的頻率沒有上面兩類高,但是也是需要掌握的。

我們先對1-3三種分析窗口函數進行演示

第4-5種:

第六種:NTILE

D. Hivesql計算兩個時間戳相差的分鍾數

1.Hive row_number() 函數的高級用法 row_num 按照某個欄位分區顯示第幾條數據

select imei,ts,fuel_instant,gps_longitude,gps_latitude,row_number() over (PARTITION BY imei ORDER BY ts ASC) as row_num from sample_data_2

2.row_num 是相互連續的,join 自身,然後時間相減可求差
create table obd_20140101 as

select a.imei,a.row_num,a.ts,COALESCE(unix_timestamp(a.ts, 'yyyy-MM-dd HH:mm:ss.S'), 0) - unix_timestamp(b.ts, 'yyyy-MM-dd HH:mm:ss.S') as intervel ,a.fuel_instant,a.gps_speed as obd_speed,a.gps_status,a.gps_longitude,a.gps_latitude,a.direct_angle,a.obdspeed from obddata_20140101 a join obddata_20140101 b on a.imei = b.imei and a.row_num = b.row_num +1

E. Hive SQL控制map數和rece數

讀取小文件較多,那麼則需要在map端進行小文件合並,參數設置如下:

-- 設置輸入文件格式

set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

-- 是否支持可切分的CombieInputFormat ,true是支持

set hive.hadoop.supports.splittable.combineinputformat = true;

set maprece.input.fileinputformat.split.maxsize = 256000000;

set maprece.input.fileinputformat.split.minsize.per.node=256000000;

set maprece.input.fileinputformat.split.minsize.per.rack=256000000;

在設置動態分區後,產生的文件數會取決於map數和分區數的大小,假設動態分區初始有N個map數,同時生成M個分區,則中間會生成N*M個文件,通常這種情況就是讓大部分數據盡量輸出到一個rece中進行處理,但是有些HiveSql不會產生rece,也就是說文件最後沒有進行合並處理,這種情況下可以用distribute by rand()的方式保證數據進行一次rece操作,實現文件的合並。

兩種處理方式參數設置如下:

a. 設置rece個數

set mapred.rece.tasks=50;

insert into table xxx

select  * from  xxx distribute by rand();

備註:set設置的參數是生成的文件個數,distribute by rand()保證數據隨機分配到50個文件中。 

b. 設置每個recer處理的數據

set hive.exec.recers.bytes.per.recer=5120000000;

insert into table xxx

select  *  from   xxx   distribute by rand();

備註:set設置的參數是生成的文件大小,distribute by rand()保證數據的平均大小是512Mb。

F. 記錄幾個Hive常用的排序函數

如果是規整的json字元串,可以先使用Hive函數get_json_object取出dySub 後面的數字,再做sum。另外也可以使用Hive函數regexp_extract,使用正則表達式抽取出dySub 後面的數字。具體可以搜索一下"lxw的大數據田地 hive函數大全",裡面有每種函數的詳細用法。 hivesql sql — 獲取指定hive表或指定文件中所有hive表的DDL,如果有按天的分區則默認執行最近7天的分區DDL。同時,table支持符合sql語法的正則表達式,如果有多個表匹配,則提示用戶選擇(使用file則自動關閉該交互功能)。

G. hive執行sql:stage-1 map = 0 rece = 0

問題描述:
在hive shell中執行sql,如
insert into person_base1 select * from person_base;

運行日誌中一直顯示如下信息

解決方式:
修改yarn-site.xml中的yarn.nodemanager.resource.memory-mb值大小(2G->4G)
原先設置

修改後設置

H. hive編寫sql可以實現計算內部收益率(Excel中的XIRR函數)嗎

方式如下:

1、打開EXCEL表格,點擊公式按鈕。

I. Hive sql及窗口函數

hive函數:

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

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是最優選擇,(指沒有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 al; —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字元串中的多個欄位

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 al  --2011-3-18  今天的日期為2011-3-18

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

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

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

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

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

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

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

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

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

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

12.select trunc(123.458,-1) from al --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 al;

2011

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

2012

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

返回值: int

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

舉例:

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

12

hive>   select month('2011-08-08') fromal;

8

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

返回值: int

說明: 返回日期中的天。

舉例:

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

8

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

24

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

返回值: int

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

舉例:

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

10

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

返回值: int

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

舉例:

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

3

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

返回值: int

說明: 返回日期中的秒。

舉例:

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

1

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

返回值: int

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

舉例:

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

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:

基本函數:

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降序)

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

hive (default)> set maprece.job.reces=3;  //先設置rece的數量 

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

row format delimited fields terminated by '\t'

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

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

外部表  create external table if not exists dept

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

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

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

多分區聯合查詢:union

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

show partitions dept_partition;

desc formatted dept_partition;

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

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

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

設置開啟分桶與rece為1:

set hive.enforce.bucketing=true;

set maprece.job.reces=-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:針對統計查詢使用

Row_Number:返回從1開始的序列

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

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

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

結果:

SUM、AVG、MIN、MAX、count

preceding:往前

following:往後

current row:當前行

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

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

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

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間隔,超過時間間隔則窗口關閉。