国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

數據庫SQL中對查詢結果排序排列序號編號,Oracle分析函數 rank,dense_rank,row_number使用和區別

2019-11-08 20:50:23
字體:
來源:轉載
供稿:網友
Oracle從8i開始就提供了3個分析函數:rank,dense_rank,row_number(1)Rank函數返回一個唯一的值,除非遇到相同的數據時,此時所有相同數據的排名是一樣的,   同時會在最后一條相同記錄和下一條不同記錄的排名之間空出排名。   (2)Dense_rank函數返回一個唯一的值,除非當碰到相同數據時,此時所有相同數據的排名都是一樣的。(3)Row_number函數返回一個唯一的值,當碰到相同數據時,排名按照記錄集中記錄的順序依次遞增。例:create table s_score( s_id number(6) ,score number(4,2));insert into s_score values(001,98);insert into s_score values(002,66.5);insert into s_score values(003,99);insert into s_score values(004,98);insert into s_score values(005,98);insert into s_score values(006,80);select    s_id    ,score   ,rank() over(order by score desc) rank   ,dense_rank() over(order by score desc) dense_rank   ,row_number() over(order by score desc) row_numberfrom s_score;   S_ID  SCORE       RANK DENSE_RANK ROW_NUMBER------- ------ ---------- ---------- ----------      3  99.00          1          1          1      1  98.00          2          2          2      4  98.00          2          2          3      5  98.00          2          2          4      6  80.00          5          3          5      2  66.50          6          4          6        排名/排序的時候,有時候,我們會想到利用偽列rownum,利用rownum確實可以解決某些場景下的問題(但是相對也比較復雜),而且有些場景下的問題卻很難解決。例:取成績前三名,并且前三名含有并列的情況    通過上面例子,我們可以直觀的看到,結果應該有5條記錄。select    s_id    ,score   ,dense_rankfrom (select    s_id    ,score   ,rank() over(order by score desc) rank   ,dense_rank() over(order by score desc) dense_rank   ,row_number() over(order by score desc) row_numberfrom s_score) twhere dense_rank <= 3;   S_ID  SCORE DENSE_RANK------- ------ ----------      3  99.00          1      1  98.00          2      5  98.00          2      4  98.00          2      6  80.00          3      如果只是簡單的想到去用rownum <= 3 得到的結果顯然不可能是正確的。組內的排名或者排序是經常遇到的一種場景。例如,取每個銷售部門內,銷售業績最好的前三名。      取每個班級內成績排名信息等等..      取每個班級內每門課成績排名第一的同學信息     drop table S_SCORE;create table S_SCORE(  S_ID  NUMBER(6),  CLASS_ID VARCHAR2(2),  COURSE VARCHAR2(20),  SCORE NUMBER(5,2));INSERT INTO S_SCORE VALUES(1001,'A','MATH','67');INSERT INTO S_SCORE VALUES(1004,'B','MATH','88');INSERT INTO S_SCORE VALUES(1002,'A','MATH','99');INSERT INTO S_SCORE VALUES(1003,'A','MATH','55');INSERT INTO S_SCORE VALUES(1001,'B','MATH','88');INSERT INTO S_SCORE VALUES(1001,'B','MATH','70');INSERT INTO S_SCORE VALUES(1001,'A','ORACLE','97');INSERT INTO S_SCORE VALUES(1004,'B','ORACLE','48');INSERT INTO S_SCORE VALUES(1002,'A','ORACLE','79');INSERT INTO S_SCORE VALUES(1003,'A','ORACLE','65');INSERT INTO S_SCORE VALUES(1001,'B','ORACLE','82');INSERT INTO S_SCORE VALUES(1001,'B','ORACLE','78');select   s_id  ,class_id  ,course  ,score  ,dense_rank() over (partition by class_id,course order by score desc) drkfrom S_SCORE;   S_ID CLASS_ID COURSE                 SCORE        DRK------- -------- -------------------- ------- ----------   1002 A        MATH                   99.00          1   1001 A        MATH                   67.00          2   1003 A        MATH                   55.00          3   1001 A        ORACLE                 97.00          1   1002 A        ORACLE                 79.00          2   1003 A        ORACLE                 65.00          3   1004 B        MATH                   88.00          1   1001 B        MATH                   88.00          1   1001 B        MATH                   70.00          2   1001 B        ORACLE                 82.00          1   1001 B        ORACLE                 78.00          2   1004 B        ORACLE                 48.00          3   select   s_id  ,class_id  ,course  ,scorefrom (select   s_id  ,class_id  ,course  ,score  ,dense_rank() over (partition by class_id,course order by score desc) drkfrom S_SCORE) twhere drk = 1;   S_ID CLASS_ID COURSE                 SCORE------- -------- -------------------- -------   1002 A        MATH                   99.00   1001 A        ORACLE                 97.00   1004 B        MATH                   88.00   1001 B        MATH                   88.00   1001 B        ORACLE                 82.00      rank()和dense_rank()用法相似,這里就不在舉例說明了。可以將上面的例子中dense_rank()替換成rank()實現。接下來,看一個使用row_number()的場景例:查看每個部門最近一筆銷售記錄select * from criss_sales order by dept_id,sale_date desc;DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT------- ----------- ---------- -----------D01     2014/5/4    G02                 80D01     2014/4/30   G03                800D01     2014/4/8    G01                200D01     2014/3/4    G00                700D02     2014/5/2    G03                900D02     2014/4/27   G01                300D02     2014/4/8    G02                100D02     2014/3/6    G00                500即,我們希望得到D01     2014/5/4    G02                 80D02     2014/5/2    G03                900這兩條記錄select  dept_id ,sale_date ,goods_type ,sale_cnt ,row_number() over (partition by dept_id order by sale_date desc)from criss_sales;DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT ROW_NUMBER()OVER(PARTITIONBYDE------- ----------- ---------- ----------- ------------------------------D01     2014/5/4    G02                 80                              1D01     2014/4/30   G03                800                              2D01     2014/4/8    G01                200                              3D01     2014/3/4    G00                700                              4D02     2014/5/2    G03                900                              1D02     2014/4/27   G01                300                              2D02     2014/4/8    G02                100                              3D02     2014/3/6    G00                500                              4select  dept_id ,sale_date ,goods_type ,sale_cntfrom (select  dept_id ,sale_date ,goods_type ,sale_cnt ,row_number() over (partition by dept_id order by sale_date desc) rnfrom criss_sales) twhere rn = 1;DEPT_ID SALE_DATE   GOODS_TYPE    SALE_CNT------- ----------- ---------- -----------D01     2014/5/4    G02                 80D02     2014/5/2    G03                900---------------------------------------------------------------------------------------------------------------
--在部門內新水排名(如果有相同名次,用dense_rank)SELECT row_number() over(PARTITION BY t.deptno  --按部門分組ORDER BY t.sal) rn, --部門內按薪水排序 t.sal, t.ename, t.deptno   FROM emp t;--分組累計計數,注意相同sal情況SELECT COUNT(*) over(PARTITION BY t.deptno ORDER BY sal) cn, t.sal, t.ename, t.deptno FROM emp t;一、排名函數1>、計算行號ROW_NUMBER函數2>、排名和密集排號RANK和DESN_RANK--示例:CREATE TABLE dbo.Sales(  empid VARCHAR(10) NOT NULL PRIMARY KEY,  mgrid VARCHAR(10) NOT NULL,  qty   INT         NOT NULL);INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES  ('A', 'Z', 300),  ('B', 'X', 100),  ('C', 'X', 200),  ('D', 'Y', 200),  ('E', 'Z', 250),  ('F', 'Z', 300),  ('G', 'X', 100),  ('H', 'Y', 150),  ('I', 'X', 250),  ('J', 'Z', 100),  ('K', 'Y', 200);CREATE INDEX idx_qty_empid ON dbo.Sales(qty, empid);CREATE INDEX idx_mgrid_qty_empid ON dbo.Sales(mgrid, qty, empid);GO###對比###select ROW_NUMBER() OVER (ORDER BY qty) AS seq,RANK()OVER (ORDER BY qty) AS seq1, DENSE_RANK() OVER (ORDER BY qty) AS seq2, *FROM Sales s			--運行結果seq	seq1	seq2	empid	mgrid	qty1	1	1	B	X	1002	1	1	G	X	1003	1	1	J	Z	1004	4	2	H	Y	1505	5	3	C	X	2006	5	3	D	Y	2007	5	3	K	Y	2008	8	4	E	Z	2509	8	4	I	X	25010	10	5	A	Z	30011	10	5	F	Z	300區別:當order by 列表不能唯一決定排序順序時,ROW_NUMBER是非確定性的。而RANK和DENSE_RANK總是確定性的。即,具有相同排序值的行總是得到相同的排名值。而RANK和DENSE_RANK的區別在于,RANK生成的排名值可能有間斷,但可以表明有多少行具有更低的排序值。DENSE_RANK生成的排名值沒有間斷。--分析函數:count(a) over (partition by b order by c)--上面的count()就是一個分析函數;over可以理解為一個關鍵字或者標識,有over就表示它前面的函數--是一個分析函數,否則就是普通的求和函數了;--()中的partition by是指定分區,或者理解為分組--()中的order by是指定該分區內的數據的順序參考:http://jingyan.baidu.com/article/597035521ff2ec8fc107404b.html
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 石首市| 密云县| 双桥区| 阳春市| 石嘴山市| 莎车县| 洛宁县| 昭觉县| 墨玉县| 莫力| 丽江市| 宁国市| 元阳县| 云林县| 新民市| 武川县| 阿城市| 泸定县| 冷水江市| 类乌齐县| 鄯善县| 蕲春县| 黎川县| 河曲县| 屯门区| 湘阴县| 康平县| 唐河县| 荃湾区| 蛟河市| 延津县| 乐平市| 镇康县| 勐海县| 万山特区| 娱乐| 名山县| 舞钢市| 丰原市| 阿坝县| 高尔夫|