ORACLE的rownum用法。用rownum來進行分頁查詢


轉自:http://blog.csdn.net/happyqiuqiang/article/details/52230051

 

 

 

一、簡單介紹一下ROWNUM是什么,可以用來干什么。

答:ROWNUM是一個序列,會根據sql語句自動給你加上一列排好順序的序號列。For example!

你有一張全班同學的各科目成績表。

 

1、然后你想給這張表按語文成績加上排名。你會怎么做?

SELECT G.ID, G.NAME, G.CHINESE, ROWNUM AS CHINESE_SORT, G.MATH, G.ENGLISH

  FROM (SELECT * FROM GRADE ORDER BY CHINESE) G

 

如果對所有科目成績加上排名序號列呢?

提示一下這回要用到left join了,left join會在下一篇文章中講解。先看下面sql代碼:

SELECT *

  FROM (SELECT T.NAME,

               T.CHINESE,

               T1.CHINESE_SORT AS CHINESE_SORT,

               T.MATH,

               T2.MATH_SORT    AS MATH_SORT,

               T.ENGLISH,

               T3.ENGLISH_SORT AS ENGLISH_SORT

          FROM GRADE T

          LEFT JOIN (SELECT G1.NAME, G1.CHINESE, ROWNUM CHINESE_SORT

                      FROM (SELECT g.NAME, g.CHINESE

                              FROM GRADE g

                             ORDER BY g.CHINESE DESC) G1) T1

            ON T1.NAME = T.NAME

          LEFT JOIN (SELECT G2.NAME, G2.MATH, ROWNUM MATH_SORT

                      FROM (SELECT g.NAME, g.MATH

                              FROM GRADE g

                             GROUP BY g.NAME, g.MATH

                             ORDER BY g.MATH DESC) G2) T2

            ON T2.NAME = T.NAME

          LEFT JOIN (SELECT G3.NAME, G3.ENGLISH, ROWNUM ENGLISH_SORT

                      FROM (SELECT g.NAME, g.ENGLISH

                              FROM GRADE g

                             GROUP BY g.NAME, g.ENGLISH

                             ORDER BY g.ENGLISH DESC) G3) T3

            ON T3.NAME = T.NAME) MyGrade

 ORDER BY MyGrade.CHINESE_SORT;

 

執行代碼后結果如下圖所示

 

 

 

二、上面的內容主要講解了ROWNUM的排序,是rownum最基本最直接的用法。不過rownum最常見的用法是用來做分頁。

還是那張成績變:

1、只顯示前語文成績前十名的學生記錄

select g.* from grade g where rownum < 10 order by chinese;

 

很簡單有沒有。

2、想知道語文成績第10名以后的學生記錄:

select g.* from grade g where rownum > 10 order by chinese;

是這樣嗎?執行一下,並沒有結果。

 

原因:文章開頭說ROWNUM是一個序列,會根據sql語句自動給你加上一列排好順序的序號列。

rownum總是為滿足條件的記錄從1開始設序號,所以rownum總是從1開始的。這理解起來並沒有問題哈。當從數據庫中找到語文成績第一名的記錄時,設序號為1,該記錄不滿足rownum>10。所以拋棄該記錄,接着從數據庫中找到語文成績第二名的記錄,又設序號為1,該記錄依然不滿足rownum>10,依次類推。所以窮盡整張表拋棄了所有記錄。

 

正確的sql應該這樣寫:

select MyGrade.*

  from (select G.*, rownum rn

          from (select g.* from grade g order by chinese) G ) MyGrade

 where MyGrade.rn >= 10;

 

先select所有記錄並按語文成績排好序,外套一個select加上序號列。這就為所有記錄固定好了排序的順序。再外套一個select取出從序號>=10 的所有記錄;

 

 

3、獲取第語文成績有潛力提升到高分階段的批次記錄,比如第6名到第10名的記錄:

 

select MyGrade.*

  from (select G.*, rownum rn

          from (select g.* from grade g order by chinese) G

         where rownum <= 10) MyGrade

 where MyGrade.rn >= 6;

 

 

 當然,下面這段sql也可以實現同樣的效果:

select MyGrade.*

  from (select G.*, rownum rn

          from (select g.* from grade g order by chinese) G

         where rownum <= 10) MyGrade

 where MyGrade.rn >= 6 and MyGrade.rn <= 10;

不過當數據量很大時,這段代碼性能就次了好多,因為它要先遍歷所有記錄,然后根據序號分頁。而對於之前的代碼,由於CBO優化模式下,Oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率,所以只是遍歷了rownum小於10的記錄,就停止了內層查詢。所以推薦使用第一種分頁方法。

好了,rownum先講到這里。如果有需要會在之后的文章中補充。下一篇文章講解inner join、left join和right join的區別和使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM