【Hive】SQL | 窗口函數詳解

2021-03-02 大數據風控與機器學習

前一篇文章【Hive】SQL | 窗口函數入門,對 Hive SQL 中的窗口函數進行一個初步的介紹,本文對窗口函數進行更加系統的介紹。

假設有如下表格(loan)。表中包含貸款人的唯一標識,貸款日期,以及貸款金額。

1.SUM(), MIN(),MAX(),AVG()等聚合函數,可以直接使用 over() 進行分區計算。

SELECT *,
/*前三次貸款的金額之和*/
SUM(amount) OVER (PARTITION BY name ORDER BY orderdate ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS pv1,
/*歷史所有貸款 累加到下一次貸款 的金額之和*/
SUM(amount) OVER (PARTITION BY name ORDER BY orderdate ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) AS pv2
FROM loan ;


其中,窗口函數over()使得聚合函數sum()可以在限定的窗口中進行聚合。本例子中,第一條語句計算每個人當前記錄的前三條貸款金額之和。第二條語句計算截至到下一次貸款,客戶貸款的總額。

窗口的限定語法為:ROWS BETWEEN 一個時間點 AND 一個時間點。時間節點可以使用:

n PRECEDING : 前n行

n FOLLOWING:後n行

CURRENT ROW :當前行

如果不想限制具體的行數,可以將 n 替換為 UNBOUNDED.比如從起始到當前,可以寫為:

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

窗口函數over()和group by 的最大區別,在於group by之後其餘列也必須按照此分區進行計算,而over()函數使得單個特徵可以進行分區。

2.NTILE(), ROW_NUMBER(), RANK(), DENSE_RANK(),可以為數據集新增加序列號。

SELECT *, NTILE(10) OVER (PARTITION BY name ORDER BY orderdate) AS f1,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY orderdate) AS f2,
RANK() OVER (PARTITION BY name ORDER BY orderdate) AS f3,
DENSE_RANK() OVER (PARTITION BY name ORDER BY orderdate) AS f4
FROM loan;

其中第一個函數是將數據按name切分成10區,並返回屬於第幾個分區。後面的三個函數的功能看起來很相似。區別在於當數據中出現相同值得時候,如何編號。

ROW_NUMBER()返回的是一列連續的序號。

RANK()對於數值相同的這一項會標記為相同的序號,而下一個序號跳過。比如{4,5,6}變成了{4,4,6}.

DENSE_RANK()對於數值相同的這一項,也會標記為相同的序號,但下一個序號並不會跳過。比如{4,5,6}變成了{4,4,5}.

3.LAG(), LEAD(), FIRST_VALUE(), LAST_VALUE()函數返回一系列指定的點

SELECT *,LAG(orderdate, 1) OVER(PARTITION BY name ORDER BY orderdate) AS last_dt,
LEAD(orderdate, 1,'1970-1-1') OVER(PARTITION BY name ORDER BY orderdate) AS next_dt,
FIRST_VALUE(orderdate) OVER(PARTITION BY name ORDER BY orderdate) AS first_dt,
LAST_VALUE(orderdate) OVER(PARTITION BY name ORDER BY orderdate) AS latest_dt
FROM loan;

LAG(n)將數據向前錯位 n 行。LEAD()將數據向後錯位 n 行。FIRST_VALUE()取當前分區中的第一個值。LAST_VALUE()取當前分區最後一個值。

4.GROUPING SET(),with CUBE, with ROLLUP 對 group by 進行限制

SELECT A,B,CFROM loan
GROUP BY substring(orderdate,1,7),orderdate
GROUPING SETS(substring(orderdate,1,7), orderdate)ORDER BY GROUPING__ID;

GROUPING__ID是GROUPING_SET()的操作之後自動生成的。生成GROUPING__ID是為了區分每條輸出結果是屬於哪一個group by的數據。

它是根據group by後面聲明的順序欄位,是否存在於當前group by中的一個二進位位組合數據。GROUPING SETS()必須先做GROUP BY操作。

比如(A,C)的group_id:group_id(A,C) = grouping(A)+grouping(B)+grouping (C) 的結果就是:二進位:101 也就是5.

如果解釋器發現group by A,C 但是select A,B,C 那麼運行時會將所有from 表取出的結果複製一份,B都置為null,也就是在結果中,B都為null.

SELECTA,B,CFROM loan
GROUP BY substring(orderdate,1,7),orderdate
with CUBEORDER BY GROUPING__ID;

with CUBE 和GROUPING_SET()的區別就是,with CUBE 返回的是group by 欄位的笛卡爾積。

SELECTA,B,CFROM loan
GROUP BY substring(orderdate,1,7),orderdate
with ROLLUPORDER BY GROUPING__ID;

with ROLLUP則不會產生第二列為鍵的聚合結果,在本例子中,只按照 substring(orderdate,1,7)進行展示。所以使用with ROLLUP時,要注意group by 後面欄位的順序。

相關焦點

  • Hive窗口函數/分析函數詳解
    hive窗口函數/分析函數在sql中有一類函數叫做聚合函數,例如sum()、avg()、max()等等,這類函數可以將多行數據按照規則聚集為一行,一般來講聚集後的行數是要少於聚集前的行數的。但是有時我們想要既顯示聚集前的數據,又要顯示聚集後的數據,這時我們便引入了窗口函數。窗口函數又叫OLAP函數/分析函數,窗口函數兼具分組和排序功能。
  • hive sql 優化心得
    下面為大家介紹一下hive的優化器以及一些常見的sql技巧。常見的優化器如果你想查看hive的優化器,可以從github上面拉一份hive的源碼,在org.apache.hadoop.hive.ql.optimizer目錄下可以看到hive裡面有哪些邏輯優化器。
  • HIVE 窗口函數實戰
    HIVE 窗口函數詳解中,我們介紹了hive窗口函數的定義和語法,本篇中我們根據例子來進行實戰。>排序窗口需求:求每個班級成績排名前三的學生。row_number()函數,唯一排序,不會生成排序相同的用戶示例和結果如下:可以看到,一班的學生三和學生四同樣為90分的學生,會按照不同的排名進行排名。rank()函數,不唯一排序,相同分數排名會相同,但後續排名會跳過。
  • Hive SQL基本使用詳解
    databases;-- 顯示所有的表show tables;-- 顯示所有分區show partitions;show partitions <表名>;-- 顯示所有函數>hive create database test;>hive use test;>hive create table if not exists employee( id bigint, username string
  • Hive SQL 第一篇:常用的內置函數
    ❝最近使用 hive sql比較多,碰到了很多函數操作,所以想簡單總結一下 hive sql 常用的函數用法,沉澱一下以便之後查閱,希望也能給大家提供一些參考。❞字符串函數字符串拼接函數-- 返回多個字符串拼接後的結果,返回string類型-- 用法concat(string a, string b...)
  • 鞏固SQL - 窗口函數&變量&數據透視圖
    但作為合格的一個數據分析師,sql的精通肯定是必不可少的,所以最近瘋狂刷sql題,同時也來總結下我以前比較少用的語法。(工作寫的是hive,為方便演示,本文章均使用Mysql8.0.16版本)一、窗口函數1、什麼是窗口函數窗口函數,也叫OLAP函數(Online Anallytical Processing,聯機分析處理),可以對資料庫數據進行實時分析處理。
  • Hive窗口函數總結與實踐
    Partition By子句也可以稱為「查詢分區子句」,非常類似於Group By,都是將數據按照邊界值分組,而Over之前的函數在每一個分組之內進行,如果超出了分組,則函數會重新計算。實例我們想要去看顧客的購買明細及月購買總額,可以執行如下的sql。
  • SparkSQL操作insert overwrite table到hive慢
    在使用spark寫hive過程中,發現最耗時的部分是將產生的結果寫入hive,舉個例子,對3g*1G表的join來講,將結果使用以下方式直接寫入hive表需要超過半小時的時間:dataframe.registerTempTable("result")sql(s"""INSERT OVERWRITE Table $outputTable PARTITION (dt ='$outputDate
  • HIVE 窗口函數詳解
    什麼是窗口函數窗口函數是 SQL 中一類特別的函數。和聚合函數相似,窗口函數的輸入也是多行記錄。不 同的是,聚合函數的作用於由 GROUP BY 子句聚合的組,而窗口函數則作用於一個窗口, 這裡,窗口是由一個 OVER 子句 定義的多行記錄。聚合函數對其所作用的每一組記錄輸 出一條結果,而窗口函數對其所作用的窗口中的每一行記錄輸出一條結果。一些聚合函 數,如 sum, max, min, avg,count 等也可以當作窗口函數使用。
  • hive時間函數詳解
    'yyyyMMddHHmmss');1635674463hive> select unix_timestamp('2021-10-31','yyyy-MM-dd HH:mm:ss') ;NULL3. to_date日期時間轉日期函數: to_date
  • 通俗易懂的學會:SQL窗口函數
    在日常工作中,經常會遇到需要在每組內排名,比如下面的業務需求:排名問題:每個部門按業績來排名topN問題:找出每個部門排名前N的員工進行獎勵面對這類需求,就需要使用sql的高級功能窗口函數了。二.什麼是窗口函數?
  • hive之窗口函數和自定義函數
    前言本篇主要講解常用的幾個窗口函數,以及如何自定義函數
  • Hive(七) ----函數
    窗口函數又叫開窗函數,屬於分析函數一種,解決複雜報表統計需求的功能。用於計算基於組的某種聚合值,和聚合函數不同,對於每個組返回多行,聚合函數隻返回一行。窗口函數制定了分析函數工作的數據窗口大小,這個數據窗口大小可能會隨著行的變化而變化。
  • Hive窗口函數row number的用法, 你肯定都會吧!
    row_number前面我們介紹窗口函數的時候說到了窗口函數的使用場景,我們也給它起了一個名字進行區分,通用窗口函數和特殊窗口函數,今天我們就來看一下排序相關的窗口函數,因為是窗口函數,並且我們說它是用來排序的,我們大概也能猜到它就是用來對窗口內的數據進行排序的其實關於排序我們前面也介紹過order by,sort by 等排序的方式Hive語法之常見排序方式
  • Hive 窗口函數最全講解和實戰
    一、窗口函數的概念
  • HiveSql基礎函數使用(三)
    前面兩篇文章介紹了一些常見且非常有用的函數,基本夠實現開發中的需求。本文主要介紹幾個select查詢函數的區別。從執行順序來說,兩者主要存在以下幾點區別 ① distinct只是將重複的行從結果中剔除出去;group by是按指定的列分組,一般這時在select中會用到聚合函數。 ②distinct是把不同的記錄顯示出來;group by是在查詢時先把紀錄按照類別分出來再查詢。
  • SQL必備:case when函數與窗口函數
    學會使用窗口函數將會使得一些關於排名或累加的複雜問題的求解變得非常簡便。例如牛客網SQL76:寫一個sql語句查詢各個崗位分數的中位數位置上的所有grade信息,並且按id升序排序。這裡涉及到了中位數的信息,用窗口函數會很方便。
  • Hive的分析函數的使用
    我們先準備資料庫、表和數據開窗分析函數相對於mysql中的聚合函數區別是:分析函數是基於某個組多個數據進行計算聚合,而聚合函數是每個組返回一行數據。FOLLOWING 最後一行所以上面的語句我們變動下select empno,ename,deptno,sal, max(sal) over(partition by deptno order by sal desc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as sal_max from emp;可以控制窗口大小
  • Hive常用的函數總結
    sqrt()函數表示對給定的數字取平方根,如下所示:hive (default)> SELECT Sqrt(5);OK_c02.23606797749979Time taken: 0.06 seconds, Fetched: 1 row(s)2、集合函數
  • Hive數據倉庫實戰
    *-bin.jar到/home/hadoop/software/hadoop2hive/lib目錄下,Hive客戶端啟動的時候會自動加載這個目錄下的所有jar包。部署就這麼簡單,我們在Linux的客戶端輸入Hive回車就進去控制臺命令窗口,後面就可以建表、查詢數據、更新等操作了。下面我們看下Hive的常用SQL操作。