1. 程式人生 > >理解over()開窗函式

理解over()開窗函式

問題:

先建一個表資料:
create table test_min_max
(
YearID number,
Line number
);


insert into test_min_max(yearID,line) values(2016,1001);
insert into test_min_max(yearID,line) values(2016,1002);
insert into test_min_max(yearID,line) values(2016,1003);
insert into test_min_max(yearID,line) values(2016,1004);
insert into test_min_max(yearID,line) values(2016,1007);
insert into test_min_max(yearID,line) values(2016,1008);
insert into test_min_max(yearID,line) values(2017,1011);
insert into test_min_max(yearID,line) values(2017,1012);
insert into test_min_max(yearID,line) values(2017,1013);
insert into test_min_max(yearID,line) values(2017,1014);
insert into test_min_max(yearID,line) values(2017,1015);
insert into test_min_max(yearID,line) values(2017,1017);
Commit;

【SQL1】
SELECT t.Yearid,
       t.Line AS Cur_Line,
       MIN(t.Line) Over(PARTITION BY t.Yearid ORDER BY t.Line) Min_Line,
       MAX(t.Line) Over(PARTITION BY t.Yearid ORDER BY t.line) Max_Line
  FROM test_min_max t;

【SQL2】
SELECT t.Yearid,
       t.Line AS Cur_Line,
       MIN(t.Line) Over(PARTITION BY t.Yearid) Min_Line,
       MAX(t.Line) Over(PARTITION BY t.Yearid) Max_Line
  FROM test_min_max t;

兩個SQL對比,僅從結果表面來看,不然得出結論:
① Min()分析函式加不加Order by結果都一致;
② Min(),Max()分析函式加Order by計算邏輯不一致。(不知道是什麼原因導致)

答覆:

如果不加ORDER BY, 就沒有視窗,計算範圍是整個分割槽;
加上ORDER BY, 預設視窗是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,就是排序後從分割槽第一行一直到當前行為止。
那麼MIN還是第一行,而MAX就是當前行了

由此我們來詳細瞭解下視窗和over()開窗函式

      視窗就是分析函式分析時要處理的資料範圍,就拿sum來說,它是sum視窗中的記錄而不是整個分組中的記錄,因此我們在想得到某個欄位的累計值時,我們需要把視窗指定到該分組中的第一行資料到當前行, 如果你指定該視窗從該分組中的第一行到最後一行,那麼該組中的每一個sum值都會一樣,即整個組的總和。

      視窗子句在這裡我只說rows方式的視窗,range方式和滑動視窗也不提。
      視窗子句中我們經常用到指定第一行,當前行,最後一行這樣的三個屬性。
第一行是 unbounded preceding,
當前行是 current row,
最後一行是 unbounded following,
視窗子句不能單獨出現,必須有order by子句時才能出現,如:

last_value(sal) over(partition by deptno 
                     order by sal 
                     rows between unbounded preceding and unbounded following)

以上示例指定視窗為整個分組。而出現order by子句的時候,不一定要有視窗子句,但效果會很不一樣,此時的視窗預設是當前組的第一行到當前行!

當省略視窗子句時:
a) 如果存在order by則預設的視窗是unbounded preceding and current row  --當前組的第一行到當前行
b) 如果同時省略order by則預設的視窗是unbounded preceding and unbounded following  --整個組

              
如果省略分組,則把全部記錄當成一個組:
a) 如果存在order by則預設視窗是unbounded preceding and current row   --當前組的第一行到當前行
b) 如果這時省略order by則視窗預設為unbounded preceding and unbounded following  --整個組

1.3、幫助理解over()的例項

例1:關注點:sql無排序,over()排序子句省略

SELECT DEPTNO, EMPNO, ENAME, SAL, 
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO)
FROM EMP;

執行結果:

        

例2:關注點:sql無排序,over()排序子句有,視窗省略

複製程式碼
SELECT DEPTNO,
       EMPNO,
       ENAME,
       SAL,
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO 
                            ORDER BY SAL DESC)
  FROM EMP;
複製程式碼

執行結果:

                   
例3:關注點:sql無排序,over()排序子句有,視窗也有,視窗特意強調全組資料

複製程式碼
SELECT DEPTNO,
       EMPNO,
       ENAME,
       SAL,
       LAST_VALUE(SAL) 
       OVER(PARTITION BY DEPTNO 
            ORDER BY SAL 
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL
  FROM EMP;
複製程式碼

執行結果:

      
例4:關注點:sql有排序(正序),over()排序子句無,先做sql排序再進行分析函式運算

複製程式碼
SELECT DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO) LAST_VALUE
  FROM EMP
 WHERE DEPTNO = 30
 ORDER BY DEPTNO, MGR;
複製程式碼

執行結果:



例5:關注點:sql有排序(倒序),over()排序子句無,先做sql排序再進行分析函式運算

複製程式碼
SELECT DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO) LAST_VALUE
  FROM EMP
 WHERE DEPTNO = 30
 ORDER BY DEPTNO, MGR DESC;
複製程式碼

執行結果:

                 

例6:關注點:sql有排序(倒序),over()排序子句有,視窗子句無,此時的運算是:sql先選資料但是不排序,而後排序子句先排序並進行分析函式處理(視窗預設為第一行到當前行),最後再進行sql排序

複製程式碼
SELECT DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       MIN(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL ASC) LAST_VALUE
  FROM EMP
 WHERE DEPTNO = 30
 ORDER BY DEPTNO, MGR DESC;
複製程式碼

執行結果:

複製程式碼
SELECT DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       MIN(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL DESC) LAST_VALUE
  FROM EMP
 WHERE DEPTNO = 30
 ORDER BY DEPTNO, MGR DESC;
複製程式碼

執行結果:


相關推薦

理解over()開窗函式

問題: 先建一個表資料: create table test_min_max ( YearID number, Line number ); insert into test_min_max(yearID,line) values(2016,1001); insert in

oracle------分析函式開窗函式over( )

一  什麼是分析函式   1  概念   分析函式是Oracle專門用於解決複雜報表統計需求的功能強大的函式,它可以在資料中進行分組然後計算基於組的某種統計值,並且每一組的每一行都可以返回一個統計值

Oracle開窗函式OVER(PARTITION BY)函式介紹

問題場景     最近在專案中遇到了對每一個型別進行求和並且求該型別所佔的比例,當時考慮求出每種型別的和,並在java中分別對每一種型別的和與總和相除求出所佔比例。後來,想到這樣有點麻煩,並且專案中持久層使用的是iBatis框架,所有考慮從SQL方面進行入手來簡化這個問題

Spark Streaming--開窗函式over()

over()開窗函式 在使用聚合函式後,會將多行變成一行,而開窗函式是將一行變成多行; 並且在使用聚合函式後,如果要顯示其他的列必須將列加入到group by中,而使用開窗函式後,可以不使用group by,直接將所有資訊顯示出來。 開窗函式適用於在每一行的最後一

sql中的 開窗函式over() 聚合函式 排名函式

轉自:http://www.cnblogs.com/nihaoyueyue/p/5894588.html 開窗函式與聚合函式一樣,都是對行的集合組進行聚合計算。它用於為行定義一個視窗(這裡的視窗是指運算將要操作的行的集合),它對一組值進行操作,不需要使用GROUP BY

Sql server 開窗函式over()的語法

用法一:與ROW_NUMBER()函式結合用,給結果進行排序編號,如圖: 程式碼如下: SELECT ROW_NUMBER() over(order by RequiredDate) num ,* from [Northwind].[dbo]

SQL 開窗函式over 與sum(),AVG(),MIN(),MAX()

1.使用over子句與rows_number()以及聚合函式進行使用,可以進行編號以及各種操作。而且利用over子句的分組效率比group by子句的效率更高。 2.在訂單表(order)中統計中,生成這麼每一條記錄都包含如下資訊:“所有訂單的總和”、“每一位客戶的所有訂單的

開窗函式over(partition by .. [order by ..])用法

1、/** 建立表 */ create table test_orer_partition_by ( prov_name varchar(20), city_name varchar(50), val_cnt int ) ; 2、/** 插入測試資料 */ insert

oracle最全面的分析函式over(Partition by...)及開窗函式詳解

大型專案中通常會涉及到統計分析相關的功能,今天筆者把oracle常用的分析函式用法和區別通過詳細的案例整理出來,希望對各位同學有幫助,也算是對自己的一個重新溫故。常用的分析函式如下所列:row_number() over(partition by ... order by .

Over子句開窗函式

開窗函式 開窗函式,開窗函式用於計算基於組的某種聚合值,它和聚合函式的不同之處是:對於每個組返回多行,而聚合函式對於每個組只返回一行。 開窗函式指定了分析函式工作的資料視窗大小,這個資料視窗大小可能會隨著行的變化而變化 開窗函式是在 ISO SQL 標準中

hive sum函式的頂級應用(配合開窗函式OVER)

首先參考http://jingyan.baidu.com/article/8cdccae969e758315413cd1e.html (可能需要使用hdfs使用者,執行hive命令) create table tmp.hive_sum(id string COMMENT

oracle分析函式技術詳解(配上開窗函式over())

分析函式是什麼? 分析函式是Oracle專門用於解決複雜報表統計需求的功能強大的函式,它可以在資料中進行分組然後計算基於組的某種統計值,並且每一組的每一行都可以返回一個統計值。 分析函式和聚合函式的不同之處是什麼? 普通的聚合函式用group by分組,每個分組返回一

MSSQL 基礎知識 開窗函式over(),orcl分析函式over()

聚合函式,都是統計中都是不包括NULL值的。 唯獨,count(*)包括NULL值。(注:count(欄位)不包括NULL值。) 開窗函式: 與 聚 合函式一樣,開窗函式也是對行集組進行聚合計算,但是它不像普通聚合函式那樣 每組只返回一個值,開窗函式可以為每組返回多個

深入理解Javascript箭頭函式中的this

今日頭條:https://m.jb51.net/article/105340.htm 新增連結描述 ES6標準新增了一種新的函式:Arrow Function(箭頭函式)。那麼下面這篇文章主要給大家介紹了箭頭函式中this的相關資料,有需要的朋友可以參考借鑑,下面來一起看看吧。 首先我們先看

理解並優化函式節流Throttle

一、函式為什麼要節流 有如下程式碼 let n = 1 window.onmousemove = () => { console.log(`第${n}次觸發回撥`) n++ } 複製程式碼 當我們在PC端頁面上滑動滑鼠時,一秒可以可以觸發約60次事件。大家也可以訪問下面的線上例子進行測試。

Oracle 的開窗函式 rank,dense_rank,row_number

1、開窗函式和分組函式的區別 分組函式是指按照某列或者某些列分組後進行某種計算,比如計數,求和等聚合函式進行計算。 開窗函式是指基於某列或某些列讓資料有序,資料行數和原始資料數相同,依然能曾現個體資料的原貌。 事例資料 create table student_scores( stu_id varch

SQL Server排名函式與排名開窗函式

什麼是排名函式?說實話我也不甚清楚,我知道 order by 是排序用的,那麼什麼又是排名函式呢? 接下來看幾個示例就明白了。 首先建立一個表,隨便插入一些資料。 ROW_NUMBER 函式:直接排序,ROW_NUMBER函式是以上升進行直接排序,並且以連續的順序給每一行資料一個唯一的序號。(即排名

SQL Server聚合函式與聚合開窗函式

以下面這個表的資料作為示例。 什麼是聚合函式? 聚合函式:聚合函式就是對一組值進行計算後返回單個值(即分組)。聚合函式在計算時都會忽略空值(null)。 所有的聚合函式均為確定性函式。即任何時候使用一組相同的輸入值呼叫聚合函式執行後的返回值都是相同的,無二義性。 COUNT(統計函式):COUNT

理解概率密度函式

概率密度函式是概率論中的核心概念之一,用於描述連續型隨機變數所服從的概率分佈。在機器學習中,我們經常對樣本向量x的概率分佈進行建模,往往是連續型隨機變數。很多同學對於概率論中學習的這一抽象概念是模糊的。在今天的文章中,SIGAI將直觀的解釋概率密度函式的概念,幫你更深刻的理解它。  

Hive 開窗函式

什麼時候用開窗函式? 開窗函式常結合聚合函式使用,一般來講聚合後的行數要少於聚合前的行數,但是有時我們既想顯示聚集前的資料, 又要顯示聚集後的資料,這時我們便引入了視窗函式。 視窗函式的語法 UDAF() over (PARTITION By col1,col2 order by c