ORACLE中的TOP-N查詢(TOP-N分析)、分頁查詢


  TOP-N查詢(TOP-N分析):就是獲取某一數據集合中的前N條記錄,實際應用中經常用到。

  Oracle中不支持SELECT TOP語句(MySQL中也沒用此語句),需要借助ROWNUM偽列來實現TOP-N查詢。

  ROWNUM偽列:是Oracle數據庫對查詢結果自動添加的一個偽列,編號從1開始。ROWNUM在物理上(查詢目標表中)並不存在,是每一次查詢過程中動態生成的,所以稱為“偽列”。因此,不允許以任何查詢基表的名稱做為前綴,連接查詢中涉及多個物理表,但也只動態生成一個偽列

1、非排序查詢TOP-N分析

例題:返回員工信息表前5條記錄

2、排序查詢TOP-N分析

  SELECT語句的執行順序:先WHERE,后ORDER BY

例題:按照工資降序排序,查詢工資最高的前5名員工的信息。

錯誤答案:

正確答案:

  內層排序,外層設定范圍(WHERE只能設定從1開始的范圍)。如rownum<=5,不能設定這樣的范圍,如rownum<=13 and rownum>=18)

  子查詢和主查詢分別會產生各自的ROWNUM偽列,而此處用的是主查詢自己的偽列。為了分析,請看下面的語句:

  “原始行號”rn是子查詢結果排序之前的行號(子查詢執行力WHERE子句,但沒有執行ORDER BY子句時的行號),結果如下:

3、分頁查詢(應用極廣)

  分頁顯示的目的是控制輸出結果集大小,將結果盡快返回

例題:按照工資逆序、分頁顯示員工信息,每頁顯示6行記錄。假定當前要顯示第3頁(即13~18行),應如何獲取該頁數據?

錯誤答案:該代碼不會返回任何查詢結果。

  分析:ROWNUM自動編號從1開始。主查詢執行時,取出子查詢結果集中的第一條記錄,並將其ROWNUM賦值為1,不符合WHERE限定的條件(13~18),於是這條記錄被過濾掉。取出子查詢結果集中的第二條記錄,並將其ROWNUM賦值為1(因為前面沒有找到過符合WHERE條件的記錄),依次類推,永遠也得不到符合條件的記錄。(我們永遠也無法繞過第一個,而直接去吃到第二個饅頭)

正確答案:加一層嵌套查詢,對子查詢中的ROWNUM的值進行“固化”處理(使得rn是物理上存在的),在主查詢中即可對其進行任意范圍的取值判斷。

  最內層排序(ORDER BY),中間層“固化”ROWNUM,最外層設定范圍(WHERE中可以設定任意范圍)。

  

select * from (select rownum r,t1.* from (select * from emp order by sal desc) t1) t2 where t2.r between 6 and 10;

優化后:

正確寫法:select * from (select rownum r,t1.* from (select * from emp order by sal desc) t1 where rownum<=10) t2 where t2.r>=6; (減少了t1表返回的數據,有優化作用)

錯誤寫法:select * from (select rownum r,t1.* from (select * from emp order by sal desc) t1 where t1.rownum<=10) t2 where t2.r>=6;(rownum是偽列,前面不能加表名修飾)

錯誤寫法:select * from (select rownum r,t1.* from (select * from emp order by sal desc) t1 where r<=10) t2 where t2.r>=6;(r在where中,而where是最先執行的,之前並沒有執行rownum r,所以導致where中的r不能被識別

 


免責聲明!

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



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