1. 程式人生 > >轉轉轉---ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法

轉轉轉---ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法

eat 往回 覓覓 表達式 value sele log win 實現

ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法 http://blog.csdn.net/yinshan33/article/details/18738229 今天在使用多字段去重時,由於某些字段有多種可能性,只需根據部分字段進行去重,在網上看到了rownumber() over(partition by col1 order by col2)去重的方法,很不錯,在此記錄分享下:

  row_number() OVER ( PARTITION BY COL1 ORDER BY COL2) 表示根據COL1分組,在分組內部根據 COL2排序,而此函數計算的值就表示每組內部排序後的順序編號(組內連續的唯一的).
與rownum的區別在於:使用rownum進行排序的時候是先對結果集加入偽列rownum然後再進行排序,而此函數在包含排序從句後是先排序再計算行號碼.
  • row_number()和rownum差不多,功能更強一點(可以在各個分組內從1開時排序).
  • rank()是跳躍排序,有兩個第二名時接下來就是第四名(同樣是在各個分組內).
  • dense_rank()l是連續排序,有兩個第二名時仍然跟著第三名。相比之下row_number是沒有重復值的.
  • lag(arg1,arg2,arg3):
  1. arg1是從其他行返回的表達式
  2. arg2是希望檢索的當前行分區的偏移量。是一個正的偏移量,是一個往回檢索以前的行的數目。
  3. arg3是在arg2表示的數目超出了分組的範圍時返回的值。
函數語法: OPAP函數語法四部分: 1.function 本身用於對窗口中的數據進行操作; 2.partitioning clause 用於將結果集分區; 3.order by clause 用於對分區中的數據進行排序; 4.windowing clause 用於定義function在其上操作的行的集合,即function所影響的範圍;
RANK()
dense_rank()
【語法】RANK ( ) OVER ( [query_partition_clause] order_by_clause )
        dense_RANK ( ) OVER ( [query_partition_clause] order_by_clause )

【功能】聚合函數RANK 和 dense_rank 主要的功能是計算一組數值中的排序值。
【參數】dense_rank與rank()用法相當,
【區別】dence_rank在並列關系是,相關等級不會跳過。rank則跳過
rank()是跳躍排序,有兩個第二名時接下來就是第四名(同樣是在各個分組內) 
dense_rank()l是連續排序,有兩個第二名時仍然跟著第三名。
【說明】Oracle分析函數
ROW_NUMBER()
【語法】ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) 
【功能】表示根據COL1分組,在分組內部根據 COL2排序,而這個值就表示每組內部排序後的順序編號(組內連續的唯一的) 
row_number() 返回的主要是“行”的信息,並沒有排名
【參數】
【說明】Oracle分析函數

主要功能:用於取前幾名,或者最後幾名等
sum(...) over ...
【功能】連續求和分析函數
【參數】具體參示例
【說明】Oracle分析函數
lag()和lead()
【語法】
lag(EXPR,<OFFSET>,<DEFAULT>) OVER ( [query_partition_clause] order_by_clause )
LEAD(EXPR,
<OFFSET>,<DEFAULT>) OVER ( [query_partition_clause] order_by_clause ) 【功能】表示根據COL1分組,在分組內部根據 COL2排序,而這個值就表示每組內部排序後的順序編號(組內連續的唯一的) lead () 下一個值 lag() 上一個值 【參數】 EXPR是從其他行返回的表達式 OFFSET是缺省為1 的正數,表示相對行數。希望檢索的當前行分區的偏移量 DEFAULT是在OFFSET表示的數目超出了分組的範圍時返回的值。 【說明】Oracle分析函數


---TEST FOR ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY COL2)
DROP TABLE TEST_Y


CREATE TABLE TEST_Y(
       ID VARCHAR2 (32) PRIMARY KEY ,
       NAME VARCHAR2 (20),
       AGE NUMBER(3 ),
       DETAILS VARCHAR2 (1000)
);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 海子,20 ,面朝大海,春暖花開);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 海子,30 ,面朝大海,春暖花開);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 貝多芬,43 ,致愛麗絲);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 普希金,34 ,假如生活欺騙了你);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 楊過,23 ,黯然銷魂掌);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 小龍女,32 ,神雕俠侶);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 李清照,21 ,尋尋覓覓、冷冷清清);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 周芷若,18 ,峨眉);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 趙敏,18 ,自由);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 張無忌,20 ,倚天屠龍記);
INSERT INTO TEST_Y VALUES(SYS_GUID(), 張無忌,30 ,倚天屠龍記);
 
SELECT * FROM TEST_Y;

----1. ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY COL2) ---查詢所有姓名,如果同名,則按年齡降序
SELECT NAME ,AGE,DETAILS,ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY AGE DESC) FROM TEST_Y;
技術分享 ----通過上面的語句可知,ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY COL2)中是按照NAME字段分組,按AGE字段排序的。 ----如果只需查詢出不重復的姓名即可,則可使用如下的語句
SELECT * FROM (SELECT NAME,AGE,DETAILS ,ROW_NUMBER() OVER( PARTITION BY NAME ORDER BY AGE DESC)RN FROM TEST_Y )WHERE RN= 1;
技術分享 ----由查詢結果可知,姓名相同年齡小的數據被過濾掉了;可以使用ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY COL2)對部分子彈進行去重處理 ----2.RANK() OVER(PARTITION BY COL1 ORDER BY COL2) ----跳躍排序
SELECT NAME ,AGE,DETAILS , RANK() OVER (PARTITION BY NAME ORDER BY AGE DESC) FROM TEST_Y;
技術分享 ----由查詢結果可知,相同的並列,下一個則跳躍到並列所替的序列後:如有兩個並列1,那麽下一個則直接排為3,跳過2; ----3.DENSE_RANK() OVER(PARTITION BY COL1 ORDER BY COL2) ----連續排序,當有多個並列時,下一個仍然連續有序 技術分享 ----由查詢結果可知,當兩個並列為1時,下一個仍連續有序為2,不跳躍到3 Lag和Lead函數可以在一次查詢中取出同一字段的前N行的數據和後N行的值。這種操作可以使用對相同表的表連接來實現,不過使用LAG和LEAD有更高的效率. Lag和Lead偏移量函數,其用途是:可以查出同一字段下一個值或上一個值,並作為新列存在表中. -----4.LAG(exp_str,offset,defval) OVER(PARTITION BY NAME ORDER BY AGE) -----exp_str 返回顯示的字段;offset是exp_str字段的偏移量,默認是1,如offset=1表示返回當前exp_str的下一個exp_str; defval當該函數無值可用的情況下返回該值。
(1) SELECT NAME ,AGE,DETAILS, LAG(NAME ,1, sue) OVER (PARTITION BY NAME ORDER BY AGE DESC ) FROM TEST_Y;

技術分享
(2) SELECT NAME ,AGE,DETAILS, LAG(NAME ,2, sue) OVER (PARTITION BY NAME ORDER BY AGE DESC ) FROM TEST_Y;
技術分享
(3) SELECT NAME ,AGE,DETAILS, LAG(NAME ,2, sue) OVER (ORDER BY AGE DESC ) FROM TEST_Y;
技術分享 ----5.LEAD(EXP_STR,OFFSET,DEFVAL) OVER(PARTITION BY NAME ORDER BY AGE) -----exp_str 返回顯示的字段;offset是exp_str字段的偏移量,默認是1,如offset=1表示返回當前exp_str的上一個exp_str; -----defval當該函數無值可用的情況下返回該值。
(1)SELECT NAME ,AGE,DETAILS, LEAD(NAME ,1, sue) OVER (PARTITION BY NAME ORDER BY AGE DESC ) FROM TEST_Y;
技術分享
 (2) SELECT NAME ,AGE,DETAILS, LEAD(NAME ,2, sue) OVER (PARTITION BY NAME ORDER BY AGE DESC ) FROM TEST_Y;
技術分享
(3) SELECT NAME ,AGE,DETAILS, LEAD(NAME ,1, sue) OVER (ORDER BY AGE DESC ) FROM TEST_Y;
技術分享 -----6.SUM(COL1) OVER([PARTITION BY COL2 ] [ORDER BY COL3])
(1) SELECT NAME ,AGE,DETAILS,ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY AGE DESC),SUM (AGE) OVER( PARTITION BY NAME ORDER BY AGE DESC) FROM TEST_Y;

技術分享

(2) SELECT NAME ,AGE,DETAILS,ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY AGE DESC),SUM (AGE) OVER( PARTITION BY NAME) FROM TEST_Y;

技術分享

(3)SELECT NAME ,AGE,DETAILS,ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY AGE DESC),SUM (AGE) OVER( ORDER BY AGE DESC NULLS LAST ) FROM TEST_Y;
技術分享
(4) SELECT NAME ,AGE,DETAILS, SUM(AGE) OVER ()  FROM TEST_Y;
技術分享

轉轉轉---ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法