婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Oracle數據庫中SQL開窗函數的使用

Oracle數據庫中SQL開窗函數的使用

熱門標簽:杭州網絡外呼系統運營商 地圖標注效果的制作 網貸外呼系統合法嗎 電銷套路機器人 手機地圖標注門店 地圖標注坐標圖標 汽車4s店百度地圖標注店 安陽企業電銷機器人供應商 鶴壁電話機器人價格

開窗函數:在開窗函數出現之前存在著很多用 SQL 語句很難解決的問題,很多都要通過復雜的相關子查詢或者存儲過程來完成。為了解決這些問題,在 2003 年 ISO SQL 標準加入了開窗函數,開窗函數的使用使得這些經典的難題可以被輕松的解決。目前在 MSSQLServer、Oracle、DB2 等主流數據庫中都提供了對開窗函數的支持,不過非常遺憾的是 MYSQL 暫時還未對開窗函數給予支持。

開窗函數簡介:與聚合函數一樣,開窗函數也是對行集組進行聚合計算,但是它不像普通聚合函數那樣每組只返回一個值,開窗函數可以為每組返回多個值,因為開窗函數所執行聚合計

算的行集組是窗口。在 ISO SQL 規定了這樣的函數為開窗函數,在 Oracle 中則被稱為分析函數。

數據表(Oracle):T_Person 表保存了人員信息,FName 字段為人員姓名,FCity 字段為人員所在的城市名,FAge 字段為人員年齡,FSalary 字段為人員工資

CREATE TABLE T_Person (FName VARCHAR2(20),FCity VARCHAR2(20),FAge INT,FSalary INT)

向 T_Person 表中插入一些演示數據:

INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Tom','BeiJing',20,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Tim','ChengDu',21,4000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Jim','BeiJing',22,3500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Lily','London',21,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('John','NewYork',22,1000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('YaoMing','BeiJing',20,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Swing','London',22,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Guo','NewYork',20,2800);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('YuQian','BeiJing',24,8000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Ketty','London',25,8500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Kitty','ChengDu',25,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Merry','BeiJing',23,3500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Smith','ChengDu',30,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Bill','BeiJing',25,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Jerry','NewYork',24,3300);

select * from t_person:

要計算所有人員的總數,我們可以執行下面的 SQL 語句:SELECT COUNT(*) FROM T_Person

除了這種較簡單的使用方式,有時需要從不在聚合函數中的行中訪問這些聚合計算的值。比如我們想查詢每個工資小于 5000 元的員工信息(城市以及年齡),并且在每行中都顯示所有工資小于 5000 元的員工個數:

select fname,
  fcity,
  fsalary,
  (select count(*) from t_person where fsalary  5000) 工資少于5000員工總數
 from t_person
 where fsalary  5000

雖然使用子查詢能夠解決這個問題,但是子查詢的使用非常麻煩,使用開窗函數則可以大大簡化實現,下面的 SQL 語句展示了如果使用開窗函數來實現同樣的效果:

select fname, fcity, fsalary, count(*) over() 工資小于5000員工數
 from t_person
 where fsalary  5000

可以看到與聚合函數不同的是,開窗函數在聚合函數后增加了一個 OVER 關鍵字。

開窗函數格式: 函數名(列) OVER(選項)

OVER 關鍵字表示把函數當成開窗函數而不是聚合函數。SQL 標準允許將所有聚合函數用做開窗函數,使用 OVER 關鍵字來區分這兩種用法。
在上邊的例子中,開窗函數 COUNT(*) OVER()對于查詢結果的每一行都返回所有符合條件的行的條數。OVER 關鍵字后的括號中還經常添加選項用以改變進行聚合運算的窗口范圍。如果 OVER 關鍵字后的括號中的選項為空,則開窗函數會對結果集中的所有行進行聚合運算。

PARTITION BY 子句:

開窗函數的 OVER 關鍵字后括號中的可以使用 PARTITION BY 子句來定義行的分區來供進行聚合計算。與 GROUP BY 子句不同,PARTITION BY 子句創建的分區是獨
立于結果集的,創建的分區只是供進行聚合計算的,而且不同的開窗函數所創建的分區也不互相影響。下面的 SQL 語句用于顯示每一個人員的信息以及所屬城市的人員數:

select fname,fcity,fage,fsalary,count(*) over(partition by fcity) 所在城市人數 from t_person

COUNT(*) OVER(PARTITION BY FCITY)表示對結果集按照FCITY進行分區,并且計算當前行所屬的組的聚合計算結果。比如對于FName等于 Tom的行,它所屬的城市是BeiJing,同
屬于BeiJing的人員一共有6個,所以對于這一列的顯示結果為6。

這就不需要先對fcity分組求和,然后再和t_person表連接查詢了,省事兒。

在同一個SELECT語句中可以同時使用多個開窗函數,而且這些開窗函數并不會相互干
擾。比如下面的SQL語句用于顯示每一個人員的信息、所屬城市的人員數以及同齡人的人數:

--顯示每一個人員的信息、所屬城市的人員數以及同齡人的人數:
select fname,
  fcity,
  fage,
  fsalary,
  count(*) over(partition by fcity) 所屬城市的人個數,
  count(*) over(partition by fage) 同齡人個數
 from t_person

ORDER BY子句:

開窗函數中可以在OVER關鍵字后的選項中使用ORDER BY子句來指定排序規則,而且有的開窗函數還要求必須指定排序規則。使用ORDER BY子句可以對結果集按
照指定的排序規則進行排序,并且在一個指定的范圍內進行聚合運算。ORDER BY子句的語法為:

ORDER BY 字段名 RANGE|ROWS BETWEEN 邊界規則1 AND 邊界規則2

RANGE表示按照值的范圍進行范圍的定義,而ROWS表示按照行的范圍進行范圍的定義;邊界規則的可取值見下表:

“RANGE|ROWS BETWEEN 邊界規則1 AND 邊界規則2”部分用來定位聚合計算范圍,這個子句又被稱為定位框架。

例子程序一:查詢從第一行到當前行的工資總和:

select fname,
  fcity,
  fage,
  fsalary,
  sum(fsalary) over(order by fsalary rows between unbounded preceding and current row) 到當前行工資求和
 from t_person

這里的開窗函數“SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN
UNBOUNDED PRECEDING AND CURRENT ROW)”表示按照FSalary進行排序,然后計算從第
一行(UNBOUNDED PRECEDING)到當前行(CURRENT ROW)的和,這樣的計算結果就是按照
工資進行排序的工資值的累積和。

“RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”是開窗函數中最常使用的定位框架,為了簡化使用,如果使用的是這種定位框架,則可以省略定位框架聲明部分,
也就是說上邊的sql可以簡化成:

select fname,
  fcity,
  fage,
  fsalary,
  sum(fsalary) over(order by fsalary) 到當前行工資求和
 from t_person

例子程序二:把例子程序一的row換成了range,是按照范圍進行定位的

select fname,
  fcity,
  fage,
  fsalary,
  sum(fsalary) over(order by fsalary range between unbounded preceding and current row) 到當前行工資求和
 from t_person

區別:

這個SQL語句與例1中的SQL語句唯一不同的就是“ROWS”被替換成了“RANGE”。“ROWS”
是按照行數進行范圍定位的,而“RANGE”則是按照值范圍進行定位的,這兩個不同的定位方式
主要用來處理并列排序的情況。比如 Lily、Swing、Bill這三個人的工資都是2000元,如果按照
“ROWS”進行范圍定位,則計算從第一條到當前行的累積和,而如果 如果按照 “RANGE”進行
范圍定位,則仍然計算從第一條到當前行的累積和,不過由于等于2000元的工資有三個人,所
以計算的累積和為從第一條到2000元工資的人員結,所以對 Lily、Swing、Bill這三個人進行開
窗函數聚合計算的時候得到的都是7000( “ 1000+2000+2000+2000 ”)。

下邊這的估計不常用:

例子程序三:

SELECT FName,
  FSalary,
  SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) 前二后二和
 FROM T_Person;

這里的開窗函數“SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 2
PRECEDING AND 2 FOLLOWING)”表示按照FSalary進行排序,然后計算從當前行前兩行(2
PRECEDING)到當前行后兩行(2 FOLLOWING)的工資和,注意對于第一條和第二條而言它們
的“前兩行”是不存在或者不完整的,因此計算的時候也是要按照前兩行是不存在或者不完整進
行計算,同樣對于最后兩行數據而言它們的“后兩行”也不存在或者不完整的,同樣要進行類似
的處理。

例子程序四:

SELECT FName, FSalary,
SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING) 后面一到三之和
FROM T_Person;

這里的開窗函數“SUM(FSalary) OVER(ORDER BY FSalary ROWS BETWEEN 1
FOLLOWING AND 3 FOLLOWING)”表示按照FSalary進行排序,然后計算從當前行后一行(1
FOLLOWING)到后三行(3 FOLLOWING)的工資和。注意最后一行沒有后續行,其計算結果為
空值NULL而非0。

例子程序五:算工資排名

SELECT FName, FSalary,
COUNT(*) OVER(ORDER BY FSalary ROWS BETWEEN UNBOUNDED PRECEDING AND
CURRENT ROW)
FROM T_Person;

這里的開窗函數“COUNT(*) OVER(ORDER BY FSalary RANGE BETWEEN UNBOUNDED
PRECEDING AND CURRENT ROW)”表示按照FSalary進行排序,然后計算從第一行
(UNBOUNDED PRECEDING)到當前行(CURRENT ROW)的人員的個數,這個可以看作是計算
人員的工資水平排名。

不再用ROWNUM 了 省事了。這個over簡寫就會出錯。

例子程序6:結合max求到目前行的最大值

SELECT FName, FSalary,FAge,
MAX(FSalary) OVER(ORDER BY FAge) 此行之前最大值
FROM T_Person;

這里的開窗函數“MAX(FSalary) OVER(ORDER BY FAge)”是“MAX(FSalary)
OVER(ORDER BY FAge RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)”
的簡化寫法,它表示按照FSalary進行排序,然后計算從第一行(UNBOUNDED PRECEDING)
到當前行(CURRENT ROW)的人員的最大工資值。

例子程序6:over(partition by XX order by XX) partition by和order by 結合

員工信息+同齡人最高工資,按工資排序

SELECT FName, FSalary,FAge,
MAX(FSalary) OVER(PARTITION BY FAge order by fsalary) 同齡人最高工資
FROM T_Person;

PARTITION BY子句和ORDER BY 可以 共 同 使用,從 而 可以 實現 更 加復 雜 的 功能

==================================================================================

高級開窗函數/ 排名的實現ROW_NUMBER();rank() ,dense_rank()

除了可以在開窗函數中使用COUNT()、SUM()、MIN()、MAX()、AVG()等這些聚合函數,
還可以在開窗函數中使用一些高級的函數,有些函數同時被DB2和Oracle同時支持,比如
RANK()、DENSE_RANK()、ROW_NUMBER(),而有些函數只被Oracle支持,比如
RATIO_TO_REPORT()、NTILE()、LEAD()、LAG()、FIRST_VALUE()、LAST_VALUE()。
下面對這幾個函數進行詳細介紹。

RANK()和DENSE_RANK()函數都可以用于計算一行的排名,不過對于并列排名的處理方式
不同;ROW_NUMBER()函數計算一行在結果集中的行號,同樣可以將其當成排名函數。這三個
函數的功能存在一定的差異,舉例如下:工資從高到低排名:

SELECT FName, FSalary,FAge,
RANK() OVER(ORDER BY fsalary desc) f_RANK,
DENSE_RANK() OVER(ORDER BY fsalary desc) f_DENSE_RANK,
ROW_NUMBER() OVER(ORDER BY fsalary desc) f_ROW_NUMBER
FROM T_Person;

rank(),dense_rank()語法:

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是連續排序,有兩個第二名時仍然跟著第三名。

row_number() 函數語法:

ROW_NUMBER()
【語法】ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) 
【功能】表示根據COL1分組,在分組內部根據 COL2排序,而這個值就表示每組內部排序后的順序編號(組內連續的唯一的) 
row_number() 返回的主要是“行”的信息,并沒有排名
【參數】
【說明】Oracle分析函數

主要功能:用于取前幾名,或者最后幾名等

===================================================================

排序函數實際場景使用:計算排行榜,排名

微信活動,每天參與,有得分,活動結束后選出排名靠前的發獎。

每參與一次,就是一個訂單,表結構:

比如要查詢期號issue為20170410期的排行榜,按得分倒敘排序,得分一樣按訂單創建先后,算排行,sql需要這么寫:

select ROWNUM rank, t.*
 from (select *
   from t_zhcw_order
   where issue = '20170410'
   order by integral desc, create_date asc) t

使用了開窗函數后就可以簡化:

select t.*,
    row_number() over(order by t.integral desc, t.create_date asc) 排名
   from t_zhcw_order t
   where issue = '20170410'

如果想只要排名范圍,可以在外邊再包一層,這也是高效分頁的一種方式:

select tt.* from (
select t.id,
  t.integral,
  t.cell,
  t.create_date,
  row_number() over(order by t.integral desc, t.create_date asc) rankNum
 from t_zhcw_order t
 where t.issue = 20170331
)tt where tt.rankNum=50

到此這篇關于Oracle數據庫中SQL開窗函數的使用的文章就介紹到這了,更多相關Oracle SQL開窗函數內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • SQL中的開窗函數詳解可代替聚合函數使用
  • Sql Server 開窗函數Over()的使用實例詳解
  • SQL Server 2012 開窗函數
  • sql server如何利用開窗函數over()進行分組統計

標簽:酒泉 河源 泰安 南陽 柳州 銀川 梧州 焦作

巨人網絡通訊聲明:本文標題《Oracle數據庫中SQL開窗函數的使用》,本文關鍵詞  Oracle,數據庫,中,SQL,開窗,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Oracle數據庫中SQL開窗函數的使用》相關的同類信息!
  • 本頁收集關于Oracle數據庫中SQL開窗函數的使用的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产亚洲人成网站| 另类综合日韩欧美亚洲| 久热成人在线视频| 国产精品久久久久久久久晋中| 91天堂素人约啪| 免费观看在线色综合| 欧美国产成人精品| 3d成人h动漫网站入口| 99re视频精品| 国产一区二区三区视频在线播放| 亚洲风情在线资源站| 亚洲欧美一区二区不卡| 国产精品污网站| 久久久国产午夜精品| 精品久久免费看| 91麻豆精品国产91久久久久| 欧美日韩国产欧美日美国产精品| 99久久婷婷国产精品综合| 国产成人精品影视| 丁香六月久久综合狠狠色| 国产成+人+日韩+欧美+亚洲| 日韩国产欧美在线播放| 久久久久久久久一| 777a∨成人精品桃花网| 欧美日韩精品一区二区三区蜜桃| 国产91丝袜在线观看| 国产激情一区二区三区桃花岛亚洲| 麻豆91小视频| 狠狠色综合日日| 国产综合一区二区| 国产精品伊人色| 成人激情小说乱人伦| 91影院在线免费观看| 久久天堂av综合合色蜜桃网 | 成人夜色视频网站在线观看| 成人性视频网站| 91蜜桃传媒精品久久久一区二区| 色成人在线视频| 欧美精品在线观看一区二区| 欧美一级片在线观看| 精品国产免费人成在线观看| 国产三级精品在线| 亚洲精品欧美综合四区| 樱桃视频在线观看一区| 性做久久久久久| 精品一区二区av| 国产一区二区女| 国产成人综合精品三级| 99视频一区二区| 色美美综合视频| 日韩精品一区二区三区四区| 中文字幕第一区第二区| 亚洲成人精品一区| 国产盗摄女厕一区二区三区| 91麻豆国产在线观看| 91精品国产入口| 亚洲视频精选在线| 久久99国内精品| 色呦呦一区二区三区| 欧美精品一区二区三区蜜桃| 亚洲色图欧美偷拍| 捆绑变态av一区二区三区| 成人sese在线| 欧美一区二区久久| 亚洲精品视频在线| 国产在线一区二区综合免费视频| 一本高清dvd不卡在线观看 | 国产欧美日韩亚州综合| 日韩福利视频网| 91福利视频久久久久| 精品欧美久久久| 亚洲国产日韩a在线播放| 东方aⅴ免费观看久久av| 正在播放亚洲一区| 亚洲美女电影在线| 成人性视频网站| 久久蜜臀精品av| 日韩中文字幕区一区有砖一区 | 97aⅴ精品视频一二三区| 亚洲自拍都市欧美小说| 亚洲男人的天堂一区二区| 亚洲综合成人在线视频| 男人的j进女人的j一区| 欧美乱妇15p| 成人ar影院免费观看视频| 欧美综合久久久| 亚洲欧洲日韩av| 国产精品一区二区你懂的| 欧美人xxxx| 亚洲狼人国产精品| 91丨九色丨国产丨porny| 国产日产欧产精品推荐色| 久草中文综合在线| 欧美精品久久久久久久久老牛影院| 中文字幕欧美日本乱码一线二线| 九九**精品视频免费播放| 欧美成人r级一区二区三区| 美女免费视频一区二区| 婷婷成人综合网| 欧美日韩成人在线| 欧美片网站yy| 在线亚洲+欧美+日本专区| 成人免费视频国产在线观看| 国产日韩欧美麻豆| 国产精品自拍网站| 久久久久久久久蜜桃| 成人免费视频caoporn| 国产精品视频你懂的| 成人国产亚洲欧美成人综合网| 国产精品污www在线观看| 97精品国产97久久久久久久久久久久| 亚洲激情在线播放| 欧美绝品在线观看成人午夜影视| 欧美日韩国产a| 日本特黄久久久高潮 | 欧美三级电影一区| 日韩一区二区在线观看视频| 国产欧美在线观看一区| 精品一区在线看| 久久精品男人天堂av| 成人aa视频在线观看| 亚洲精品免费一二三区| 欧美二区乱c少妇| 国产一区二区三区综合| 国产精品私房写真福利视频| 91在线你懂得| 91丨九色丨尤物| 亚洲成a人v欧美综合天堂下载| 美国十次了思思久久精品导航| 成人高清伦理免费影院在线观看| 欧美在线免费观看视频| 国产精品久久久久影院亚瑟| 亚洲图片欧美视频| 91精品国产综合久久精品麻豆 | 国产精品久久看| 欧美午夜精品一区二区三区 | 亚洲高清久久久| 91精品欧美福利在线观看| 国产成人综合视频| 亚洲成人免费视| 国产精品二区一区二区aⅴ污介绍| 欧美网站一区二区| 国产成人av自拍| 亚洲成年人影院| 国产精品三级电影| 色婷婷综合中文久久一本| 欧美日韩三级一区| 亚洲日本一区二区| av电影在线观看不卡 | 日日噜噜夜夜狠狠视频欧美人| 日本久久电影网| 不卡一区二区在线| 成人动漫中文字幕| 9l国产精品久久久久麻豆| 18欧美乱大交hd1984| 日韩欧美123| 久久成人精品无人区| 日韩欧美的一区| 亚洲图片自拍偷拍| 欧美一a一片一级一片| 亚洲一二三专区| 国产精品美女久久福利网站| 欧美精品777| 91麻豆国产福利在线观看| 天天综合色天天综合色h| 国产精品嫩草影院av蜜臀| 精品粉嫩超白一线天av| 日韩一区二区三区四区五区六区| 在线观看日韩av先锋影音电影院| 不卡av免费在线观看| 成人黄色在线看| 国产成人av一区二区三区在线| 韩日欧美一区二区三区| 免费看日韩精品| 人人爽香蕉精品| 欧美aⅴ一区二区三区视频| 午夜精品aaa| 亚洲国产精品久久人人爱蜜臀| 亚洲精品国产无天堂网2021 | 欧美大片在线观看一区| 欧美精品日韩精品| 91精品国产高清一区二区三区| 欧美美女一区二区三区| 欧美日韩高清不卡| 欧美日韩一区久久| 欧美日韩国产bt| 欧美一区二区精品在线| 欧美一级片免费看| 久久亚洲精精品中文字幕早川悠里| 精品国产一区a| 精品区一区二区| 国产精品色眯眯| 亚洲国产中文字幕在线视频综合| 亚洲gay无套男同| 乱中年女人伦av一区二区| 国产精品一卡二卡| 一本一道久久a久久精品| 这里只有精品免费| 国产性色一区二区| 亚洲精品久久7777|