Apache Hive進階實戰

Udf   單行函數:一行輸入一行輸出

Udaf   多行函數:多行輸入一行輸出

Udtf   用戶表函數:一行輸入多行輸出,主要用在側視圖

Hive視圖概述:

視圖是一個元數據,只能在MySQL DataStore中找到

視圖是一種邏輯結構,通過在虛擬表中隱藏子查詢、連接和函數來簡化查詢,數據查詢的快捷方式,把複雜的查詢放在view裏

Hive視圖不存儲數據或獲得物化

一旦創建了視圖,它的模式就會立即凍結,元數據就會被存起來,查詢才能顯示出來

如果刪除或更改了基礎表,則查詢視圖將失敗

視圖是只讀的,不能用作加載/插入/修改的目標,只能進行查詢

Hive視圖常用操作:

建立視圖:CREATE VIEW view_name AS SELECT statement;

建立視圖支持:CTE,ORDER BY,LIMIT,JOIN等等

查找視圖用:SHOW TABLES; (hive v2.2.0之後才支持SHOW VIEWS)

顯示View定義用:SHOW CREATE TABLE view_name;

刪除視圖:DROP view_name;

更改視圖屬性:ALTER VIEW view_name SET TBLPROPERTIES ('comment' = 'This is a view');

更改視圖定義:ALTER VIEW view_name AS SELECT statement;

顯示錶的格式屬性:SHOW TABLE FORMATE;

使用show views查看是否支持該命令,不支持的話就使用SHOW CREATE TABLE desc formatted tablename; 可以查看錶的格式和詳細信息,這裏可以得到Table Type ,也可以得到表的location 根據Table Type值可以知道表是內部表還是外部表。是表還是視圖。

Hive側視圖:

應用表生成函數,將函數的輸入和輸出連接在一起

即使輸出爲空,LATERAL VIEW OUTER也會生成結果

支持多個水平

    SELECT * FROM table_name

    LATERAL VIEW explode(col1) myTable1 AS myCol1

    LATERAL VIEW explode(myCol1) myTable2 AS myCol2;

通常用於規範化行或JSON解析器

select * from work lateral view outer explode(split(null, ',')) a as loc;

explode會把這個數組拆成多個行

使用outer關鍵字可以把null也輸出出來

Complier 編譯器 compile(編譯)

Optimizer 優化器

Executor 執行器

Hive SELECT(數據映射):

SELECT語句用於項目符合WHERE/JOIN指定的查詢條件的行

Hive SELECT語句是數據庫標準SQL的子集

SELECT 1;   //直接返回這個常量,可以測試自定義函數

SELECT [DISTINCT] column_nam_list FROM table_name;

//僅從 "table_name" 表的 "column_name, column_name" 列中選取唯一不同的值,也就是去掉 "column_name, column_name" 列中的重複值。

//在表中,一個列可能會包含多個重複值,但有時希望僅僅列出不同(distinct)的值。

SELECT * FROM table_name;

SELECT * FROM employee LIMIT 5;

//限制返回的行數

 

CTE:WITH t1 AS (SELECT …) SELECT * FROM t1

CTE就是CTAS加上WITH,子查詢嵌套使用Common Table Expression,把查詢寫的更清楚

CREATE TABLE cte_employee AS WITH

r1 AS (SELECT name FROM r2 WHERE name = 'Michael'),

r2 AS (SELECT name FROM employee WHERE sex_age.sex= 'Male'),

r3 AS (SELECT name FROM employee WHERE sex_age.sex= 'Female')

SELECT * FROM r1 UNION ALL SELECT * FROM r3;

嵌套查詢:SELECT * FROM (SELECT * FROM employee) a;(後面一定要加別名,否則會報錯)

Hive SELECT in Advance(進階語句)

正則表達式列規範

SET hive.support.quoted.identifiers = none;(設置好就能使用了)

SELECT `^o.*` FROM offers;

虛擬列(兩個連續下劃線,對數據驗證有用)

INPUT__FILE__NAME,這是映射器任務的輸入文件的名稱(文件地址)

         BLOCK__OFFSET__INSIDE__FILE,它是當前的全局文件(塊大小)

 

Hive中JOIN概述:

JOIN語句用於將兩個或多個表中的行組合在一起,join要有關聯條件

Hive JOIN語句類似於數據庫連接,Hive不支持不平等連接,join的表的column要相等

INNER JOIN,OUTER JOIN(RIGHT JOIN,LEFT JOIN, FULL OUTER JOIN)其中的OUTER可以省略掉,CROSS JOIN(完全連接,在兩個表沒有相同元素時使用,或者使用:笛卡兒積/JOIN ON 1=1,隱藏JOIN(INNER JOIN不使用JOIN關鍵字但是使用where和逗號,來分割表),但是如果兩個表都有100行,同時查詢就會一口氣查10000行數據。

JOIN用在WHERE子句之前

Area C = Circle1 JOIN Circle2

Area A = Circle1 LEFT OUTER JOIN Circle2

Area B = Circle1 RIGHT OUTER JOIN Circle2

AUBUC = Circle1 FULL OUTER JOIN Circle2

求A和B異差集的方法

求A和B右連接A爲null的部分,UNION上A和B左連接B爲null的部分

Inner JOIN, select * from a join b on a.k = b.k

Implicit JOIN, select * from a, b where a.k = b.k

Outer JOIN, select * from a left join b where a.k = b.k

Cross JOIN, select * from a join b where 1 = 1 

Inequality JOIN (2.2.0之後的版本支持)   【異差集】

Hive中MAPJOIN

必須是一個大表JOIN一個小表,把小表的數據進行一個複製,把小表複製多份放到大表所在的節點上,把小表數據在大表上過濾一遍

MAPJOIN語句意味着只通過map執行連接,而不執行reduce作業

MAPJOIN語句將所有數據從小表讀入內存並廣播到所有映射

一旦設置hive.auto.convert.join = true,Hive自動轉換JOIN成爲MAPJOIN如果可能的話,在運行時檢查MAPJOIN hint,這是默認的

SELECT /*+ MAPJOIN(employee) */ emp.name, emph.sin_number

FROM employee emp JOIN employee_hr emph ON emp.name = emph.name;

MAPJOIN操作符不支持以下操作:

在UNION ALL, LATERAL VIEW, GROUP BY/JOIN/SORT BY/CLUSTER BY/DISTRIBUTE BY後面使用MAPJOIN

不能在UNION, JOIN和其他MAPJOIN後面使用MAPJOIN

Hive集合操作Union

UNION ALL,合併後保留副本

UNION,刪除重複,自v1.2.0以來的支持

可以在頂層查詢中使用

所有子集數據必須具有相同的名稱和類型。否則,將執行隱式轉換,並且可能存在運行時異常。

ORDER BY、SORT BY、CLUSTER BY、distribution BY或LIMIT用於union後的整個結果

    select key from (select key from src1 order by key limit 10) sub union all

    select key from src2 order by key limit 10

如果在union之前排序要用子查詢的形式加上()進行order by

Hive中集合的其他操作:

其他set操作符可以使用JOIN/OUTER JOIN來實現

MINUS(集合和集合之間求子集):

SELECT a.name

FROM employee a

LEFT JOIN employee_hr b

ON a.name = b.name

WHERE b.name IS NULL;

INTERCEPT(集合和集合之間求交集):

SELECT a.name

FROM employee a

JOIN employee_hr b

ON a.name = b.name;

Hive中使用LOAD進行移動數據:

要在Hive中移動數據,它使用LOAD關鍵字。當不適用LOCAL字段時,移動到這裏意味着原始數據被移動到目標表/分區,並且不再存在於原始位置。

不太推薦使用,不是標準的hive語句,load不能重複運行,只是進行文件轉移,並沒有進行塊操作

load data local inpath '/tmp/hivedemo/data/employee2.txt' overwrite into table employee_external;

load data inpath '/tmp/hivedemo/data/employee2.txt' overwrite into table employee_external;

LOCAL指定文件位於主機中,當使用LOCAL時而且本地文件不會被刪除

不當不適用LOCAL在HDFS中進行操作時,本質就是把路徑改變,並不是把文件的儲存位置改變

OVERWRITE覆蓋用於決定是否追加或替換現有數據,加就是清空,不加就是不清空

Hive中表插入要點:

要將數據插入表/分區,Hive使用insert語句

INSERT比DBMS中的INSERT弱

INSERT支持OVERWRITE和INTO語法(但是使用OVERWRITE不能指定具體列了)

Hive支持從同一個表中插入多個數據

TABLE關鍵字在INSERT INTO中是可選的,但是建議寫出來

INSERT INTO、可以像INSERT INTO T (z, x, c1)插入到T (z, x, c1)

INSERT INTO table_name VALUES,支持插入值列表

所有數據插入必須具有相同數量的指定列,或在未指定時具有相同數量的所有列

示例:

Hive中文件插入要點

要將數據插入/導出文件,Hive還使用insert語句

文件插入只支持OVERWRITE

Hive支持從同一個數據源/表進行多次插入

LOCAL關鍵字支持寫入本地文件系統。

默認情況下,寫入的數據爲文本,列之間以^A和行換行隔開。如果任何列不是基元類型,則將這些列序列化爲JSON。

支持行格式導出文件到不同的格式CSV,JSON等。

示例:

Hive中的數據交換[EX|IM]PORT

IMPORTEXPORT語句用於數據遷移(是HiveHadoop之間的導入和導出)

所有數據和元數據在沒有數據庫的情況下導出/導入

EXPORT語句在名爲_metadata的文件中導出名爲data和metadata的子目錄中的數據

    EXPORT TABLE employee TO '/tmp/output3';

    EXPORT TABLE employee_partitioned partition (year=2014, month=11) TO '/tmp/output5';

EXPORT之後,我們可以手動將導出的文件複製到其他HDFS。然後,使用import語句導入它們

     IMPORT TABLE empolyee_imported FROM '/tmp/output3';

IMPORT TABLE employee_partitioned_imported FROM '/tmp/output5’;

Hive分類數據ORDER BY

ORDER BY (ASC|DESC)類似於標準SQL

ORDER BY僅使用一個reducer執行全局數據排序。

雖然ORDER BY很慢,我們應該儘早放置過濾器

ORDER BY支持使用CASE WHEN或表達式

ORDER BY支持設置這個位置參數:

set hive.groupby.ordervy.position.alias = true;

排序時使用select * from b order by case when num is null then 101 else num end;或者select * from b order by nvl(num,101);來把數據庫裏null排到最後

Hive排序數據—SORT BY:

SORT BY(ASC|DESC)決定如何排序每個reducer中的數據,是每一個reduce內部的排序

當reducer的數量設置爲1時,它等於ORDER BY

SORT BY通常不單獨使用

by列後面的字段必須出現在SELECT列的列表中(*字標籤是可以的)

有1個以上的reducer時,數據排序不正確,因爲每一個reduce都進行SORT BY合起來可能就不正確了

例如:SET mapred.reduce.tasks = 2;【這個在select中可以用,但是insert中就不能用了】

Hive排序數據—DISTRIBUTE BY

DISTRIBUTE BY類似於標準SQL中的GROUP BY語句

它確保具有匹配列值的行將被分區到相同的簡化程序中

它不對每個reduce的輸出進行排序

它通常使用在SORT BY語句之前(partition => reducer)

by列必須出現在SELECT列列表中(*字標籤是可以的)

示例:(績效評估 典型應用)

         SELECT department_id , name, employee_id, evaluation_score

FROM employee_hr DISTRIBUTE BY department_id SORT BY evaluation_score DESC;

因爲使用DISTRIBUTE BY + SORT BY會快一些

DISTRIBUTE BY決定了數據按什麼劃分,SORT BY在同一個地方進行局部排序,因爲在這個例子裏不同部門進行排序是沒有意義的

Hive排序數據—CLUSTER BY

CLUSTER BY = DISTRIBUTE BY + SORT BY在同一列

CLUSTER BY不支持ASC | DESC

by列必須出現在SELECT列列表中(*字標籤是可以的)

爲了充分利用所有的reducer方法進行全局排序,我們可以先使用CLUSTER BY,然後再使用ORDER BY

示例:

SELECT name, employee_id FROM employee_hr CLUSTER BY name;

SELECT後應用所有排序語句。

如果在select中使用別名,應該在order之後使用別名

最常用的是order by,應用範圍比較廣,它是全局排序,只用到一個reduce,但是有的時候需求是不需要統一進行排序的,比如比賽的排名只要求單項比賽的排名就可以;因爲剩下兩個都需要對數據非常瞭解,如果要用其他的記得先用DISTRIBUTE BY,查看數據之後再使用ORDER BY

而CLUSTER BY理論上講速度可以比ORDER BY快,但是ORDER BY適用場合比較多

Hive分組GROUP BY

Hive的基本內置聚合函數通常和GROUP BY子句一起使用

如果沒有指定GROUP BY子句,默認情況下,它將聚合整個表。

除了聚合函數外,所選的所有其他列也必須包含在GROUP BY

select afferId, max(offervalue) from offers group by category;

offerId也必須放到group by裏面

GROUP BY支持使用CASE WHEN或表達

GROUP BY 支持位置number:hive.groupby.orderby.position.alias = true

Hive的聚合條件HAVING

自從Hive 0.7.0,所以添加了have來支持GROUP BY的聚合結果的條件過濾

通過使用HAVING,我們可以避免在GROUP By之後使用子查詢

HAVING之後,我們也可以使用表達式,但不建議這樣使用

並且HAVING可以替代WHERE但是也不建議這麼做,因爲這不是一種高效的寫法

HAVING更擅長在使用function的時候使用,也就是聚合條件的時候,但是普通條件用WHERE就可以,而且WHERE不能用在聚合函數上

Hive基本聚合:

我們經常使用內置的聚合函數來進行數據聚合

聚合總是與GROUP BY一起使用

聚合函數可以應用於列或表達式

沒有GROUP BY,聚合GROUP BY所有列

GROUP BY之後的列必須在SELECT列列表中(因爲select選出的數據可能會有重複如果不加Group就不能正常計算出)

在NULL上的聚合爲0,選擇count(NULL) = 0

沒有兩個聚合可以具有不同的列

SELECT count(DISTINCT col1), count(DISTINCT col2) FROM test GROUP BY col3;(不允許

SELECT count(DISTINCT col1), sum(DISTINCT col1) FROM test GROUP BY col3; (允許

注意一些函數

Max,min,count,sum,avg

max(distinct col),avg(distinct col)等等

collect_set,collect_list(返回每個組列中的對象集/列表

Hive高級聚合—GROUPING SETS

GROUP BY中的groups SETS子句允許我們指定多餘一個的記錄集中的GROUP BY選項 = GROUP BY UNION GROUP BY…

使用GROUPING SETS分組集聚合查詢

具有GROUP BY的等效聚合查詢

SELECT a, b, SUM( c ) FROM tab1

GROUP BY a, b

GROUPING SETS ((a, b), a, b, ( ))

SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b UNION

SELECT a, null, SUM( c ) FROM tab1 GROUP BY a, null

UNION

SELECT null, b, SUM( c ) FROM tab1 GROUP BY null, b

UNION

SELECT null, null, SUM( c ) FROM tab1

SELECT a, b, SUM( c ) FROM tab1

GROUP BY a, b GROUPING SETS ( (a,b), a)

SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b UNION

SELECT a, null, SUM( c ) FROM tab1 GROUP BY a

SELECT a, b, SUM(c) FROM tab1

GROUP BY a, b GROUPING SETS ( (a,b) )

SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b

SELECT a,b, SUM( c ) FROM tab1

GROUP BY a, b GROUPING SETS (a,b)

SELECT a, null, SUM( c ) FROM tab1 GROUP BY a UNION

SELECT null, b, SUM( c ) FROM tab1 GROUP BY b

Hive高級聚合—CUBE|ROLLUP

一般的語法是GROUP BY WITH CUBE/ROLLUP

CUBE創造了多維數據集在其參數中創建列集的所有可能組合的求部分和。一旦我們在一組維度上計算了一個CUBE,我們就可以得到這些維度上所有可能的聚合問題的答案,所有組合都表達出來

ROLLUP子句用於在維度的層次結構級別上計算聚合

使用ROLLUP/CUBE聚合查詢

具有GROUP BY的等效聚合查詢

SELECT a, b, SUM( c ) FROM tab1

GROUP BY a, b, c WITH CUBE

SELECT a, b, SUM( c ) FROM tab1

GROUP BY a, b, c GROUPING SETS

( (a, b, c), (a, b), (b, c), (a, c), (a), (b), (c), ( ))

SELECT a, b, SUM( c ) FROM tab1

GROUP BY a, b, c WITH ROLLUP

SELECT a, b, SUM( c )

FROM tab1 GROUP BY a, b, c

GROUPING SETS ( (a, b, c), (a, b), (a), ( ))

Hive窗口功能概述:

SYNTAX (語法解析)

排序:ROW_NUMBER,RANK,DENSE_RANK,NLITE,ERCENT_RANK

聚合:COUNT,SUM, AVG,MAX,MIN

分析:CUME_DIST,LEAD,LAG,FIRST_VALUE,LAST_VALUE

WINDOW clause(窗口的定義)

Case Study(案例分析)

Hive窗口功能語法:

自Hive 0.11.0添加之後,Hive window函數是一組特殊的函數,它掃描多個輸入行來計算每個輸出值。

解析函數功能強大,不受GROUP BY的限制

語法解析

Function (arg1,..., arg n) OVER ([PARTITION BY <...>] [ORDER BY <....>] [<window_clause>])

PARTITION BY類似於GROUP。如果沒有分區,就全部分區

如果沒有ORDER BY,則無法定義window_clause

windows_clause不常用, 但功能很強

過濾其結果必須在外面一層

可同時用多個函數

 

窗口排序功能—排序類:

ROW_NUMBER一個惟一的編號在結果集中每一行基於PARTITION內的ORDER BY子句(1234)

RANK:相等的行用相同的數字排序 (11144)

DENSE_RANK:在普通的RANK函數中,我們可以看到行數之間的差距。DENSE_RANK是一個沒有間隙的函數。(11122)

NLITE:它將有序數據集劃分爲桶數,併爲每一行分配適當的桶數。它可以用於將行分割成相等的集合,併爲每一行分配一個數字。

PERCENT_RANK:(目前排名- 1)/(總行數- 1)。因此,它返回一個值相對於一組值的百分比等級(%)。

示例:

SELECT name, dept_num, salary,

ROW_NUMBER() OVER () AS row_num,

//寫出這是第幾列

RANK() OVER (PARTITION BY dept_num ORDER BY salary) AS rank,

//按照工資大小排列返回具體第幾

DENSE_RANK() OVER (PARTITION BY dept_num ORDER BY salary) AS dense_rank,

//和單獨的rank有區別,沒有相同排名之後造成的差

PERCENT_RANK() OVER(PARTITION BY dept_num ORDER BY salary) AS percent_rank,

//相對排序(目前排名- 1)/(總行數- 1)顯示的是百分比

NTILE(2) OVER(PARTITION BY dept_num ORDER BY salary) AS ntile

//分成兩個桶,按照部門分區,salary進行排序

FROM employee_contract

ORDER BY dept_num, salary;

窗口聚合函數—聚合類:

COUNT:計數,可以和DISTINCT一起用,從v2.1.0開始沒有ORDER BY和window_cause。完全支持v2.2.0。

SELECT COUNT(DISTINCT a)

OVER (PARTITION BY c ORDER BY d ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)

FROM T

SUM:聚合,

AVG : 均值

MAX/MIN:最大/小值

Hive 2.1.0開始在OVER子句支持中聚合函數

SELECT rank() OVER (ORDER BY sum(b)) FROM T GROUP BY a;

示例:

SELECT name, dept_num, salary,

COUNT(*) OVER (PARTITION BY dept_num) AS row_cnt,

//不支持GROUP BY

//COUNT(DISTINCT *) OVER (PARTITION BY dept_num) AS row_cnt_dis,

SUM(salary) OVER(PARTITION BY dept_num ORDER BY dept_num) AS deptTotal,

//各個部門的工資和

SUM(salary) OVER(ORDER BY dept_num) AS runningTotal1,

//進行但是在部門層次上進行工資相加

SUM(salary) OVER(ORDER BY dept_num, name rows unbounded preceding) AS runningTotal2,

// 用name作爲一個邊界成爲一個窗口函數

AVG(salary) OVER(PARTITION BY dept_num) AS avgDept,

//部門間的均值

MIN(salary) OVER(PARTITION BY dept_num) AS minDept,

//部門間的最小值

MAX(salary) OVER(PARTITION BY dept_num) AS maxDept

//部門間的最大值

FROM employee_contract

ORDER BY dept_num, name;

//其實總體的這個ORDER BY並不起什麼作用,主要還是窗口函數裏面的ORDER BY起作用

窗口分析函數—分析類:

CUME_DIST:(行數<=當前行)/(總行數)

LEAD/LAG:lead/lag(value_expr [,offset[,default]]),用於返回下一行/上一行數據。可以選擇指定行數(value_expr)。如果未指定行數(偏移量),則默認爲一行。如果未指定默認值,則返回[,default]null

FIRST_VALUE:它從有序集返回第一個結果。

LAST_VALUE:它返回有序集的最後一個結果。

示例:

SELECT name, dept_num, salary,

LEAD(salary, 2) OVER(PARTITION BY dept_num ORDER BY salary) AS lead,

//把salary的行數向前移動兩行,以部門分組,就是把每組的數據各自向前移動兩行

LAG(salary, 2, 0) OVER(PARTITION BY dept_num ORDER BY salary) AS lag,

//把salary的行數向後移動兩行,以部門分組,就是把每組的數據各自向前移動兩行

FIRST_VALUE(salary) OVER (PARTITION BY dept_num ORDER BY salary) AS first_value,

//工資的第一個值

LAST_VALUE(salary) OVER (PARTITION BY dept_num ORDER BY salary) AS last_value_default,

LAST_VALUE(salary) OVER (PARTITION BY dept_num ORDER BY salary

RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_value

//工資的最後第一個值,但是默認的求最後一個值是有問題的所以要採用RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING才能正常使用LAST

FROM employee_contract

ORDER BY dept_num, salary;

對於LAST_VALUE,使用默認的窗口子句,結果可能有點出乎意料。這是因爲默認窗口子句的範圍是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,在本例中這意味着當前行始終是最後一個值。將窗口子句更改爲RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING給出了我們可能期望的結果

窗口定義詳解:

子句[<window_clause>]用於進一步細分結果並應用解析函數

有兩種類型的窗口:行類型窗口和範圍類型窗口。

RANK,NTILE,DENSE_RANK,CUME_DIST,PERCENT_RANK,LEAD,LAG和ROW_NUMBER函數還不支持與window clause一起使用(window clause有一定的侷限性)

行類窗口:

對於行類型窗口,定義是根據當前行之前或之後的行號。row window clause的一般語法如下:

    ROWS BETWEEN <start_expr> AND <end_expr>

<start_expr>可以是以下任意一種:

    UNBOUNDED PRECEDING:窗口從分區的第一行開始

     CURRENT ROW:當前行數

    N PRECEDING or FOLLOWING:在當前行之前或之後的N行

<end_expr>可以是以下任意一種:

    UNBOUNDED FOLLOWING:窗口在分區的最後一行結束

    CURRENT ROW:當前行數

    N PRECEDING or FOLLOWING:在當前行之前或之後的N行

UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING代表所有的行

排序時如果ORDER BY 列不充分區分序列, ROW順序可能隨機(儘量用上主鍵列) , 會影響結果

行類窗口圖解:

示例:

SELECT name, dept_num AS dept, salary AS sal,

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) win1,

//當前行和當前行前兩行的最大值,都用各個部門分組

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING) win2,

//當前行前兩行和最後一行的最大值,都用各個部門分組

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING) win3,

//當前行前一行和當前行後兩行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) win4,

//當前行前兩行和當前行前一行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) win5,

//當前行後一行和當前行後兩行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN CURRENT ROW AND CURRENT ROW) win6,

//當前行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) win7,

//當前行和當前行後一行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) win8,

//當前行和最後一行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) win9,

//第一行和當前行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) win10,

//第一行和當前行後一行的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) win11,

//第一行和最後一的最大值

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name ROWS 2 PRECEDING) win12

//當前行前兩行和當前行的最大值

FROM employee_contract

ORDER BY dept, name;

範圍類窗口:

與行類型窗口(以行爲單位)相比,範圍類型窗口(以分區中當前行之前或之後的值/距離爲單位)必須是數字或日期類型。目前,範圍類型窗口只支持一個ORDER BY列。

SUM(close) RANGE BETWEEN 500 PRECEDING AND 1000 FOLLOWING

根據與當前行值的距離選擇行。假設當前值爲3000,這個框架將包括分區中工資範圍在2500到4000之間的行。

示例:

SELECT name, dept_num AS dept, salary AS sal,

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) win1,

//當前行前兩行和當前行的最大值

salary - 1000 as sal_r_start,

salary as sal_r_end,

MAX(salary) OVER (PARTITION BY dept_num ORDER BY name

RANGE BETWEEN 1000 PRECEDING AND CURRENT ROW) win13

//當前行減1000和當前行的最大值

FROM employee_contract

ORDER BY dept, name;

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