oracle分頁顯示方法
一、使用rownum分頁顯示方式
方式1:SELECT *
FROM (SELECT ROWNUM r, a.* FROM b$i_exch_info a WHERE ROWNUM <= 10)
WHERE r >= 5;
方式2:
SELECT *
FROM (SELECT ROWNUM r, a.* FROM b$i_exch_info a)
WHERE r BETWEEN 5 AND 10;
方式3:
SELECT * FROM b$i_exch_info WHERE ROWNUM <= 10 MINUS
SELECT * FROM b$i_exch_info WHERE ROWNUM < 5;
二、使用分析函數row_number分頁顯示
SELECT *
FROM (SELECT e.*, row_number() over(ORDER BY g3e_fid) r
FROM b$i_exch_info e) a
WHERE a.r >= 5
AND a.r <= 10;
注意事項
1.
SELECT * FROM user_objects
WHERE /*object_id <100
AND*/ ROWNUM = 1;
--之前的版本
SELECT * FROM user_objects
WHERE object_id <100
AND ROWNUM <= 1;
2.
rownum采用大於號>時 其值必須小於1,否則查詢無結果
SELECT * FROM user_objects
WHERE ROWNUM >1;
>= 時其值必須小於或等於1,否則查詢無結果
SELECT * FROM user_objects
WHERE ROWNUM >=2;
= 時其只能等於1,否則查詢無結果
SELECT * FROM user_objects
WHERE ROWNUM =2;
3.ROWNUM 和Order BY
在使用ROWNUM 時,只有當Order By 的字段是主鍵時,查詢結果才會先排序再計算ROWNUM:
g3e_ano是主鍵
SELECT g3e_ano,g3e_username FROM g3e_attribute WHERE ROWNUM <= 5 ORDER BY g3e_ano;
1 備注
1002 組件序號
1008 組件序號
1009 組件序號
1010 組件序號
--以下查詢因為ORDER BY的g3e_username不是主鍵,所以執行時是先線取出該表的6條數據,再對g3e_username排序
SELECT g3e_ano,g3e_username FROM g3e_attribute WHERE ROWNUM <= 5 ORDER BY g3e_username;
111003 設施特征唯一號
113203 設施特征唯一號
50110 設施特征唯一號
1510103 設施特征唯一號
112003 設施特征唯一號
--如果需要對非主鍵字段先排序再去取前n 條數據,可以通過子查詢的方式實現:
select g3e_ano, g3e_username
from (select g3e_ano, g3e_username
from g3e_attribute
order by g3e_username)
where rownum <= 5;
--每頁按10條記錄輸出(如果被排序的字段有重復值,使用rownum會出現一個問題):
--觀察下面兩個語句的輸出結果會發現其中55461451和55461209是在兩個查詢中都出現了。而fid在表中都是唯一記錄的,
--說明這個輸出結果是錯誤的
錯誤原因:SORT (ORDER BY STOPKEY)這種快速排序方法由於是根據數據分組來選擇數據的,不是根據整個表的數據進行排序,所以N
值不同,數據的分組也不同,導致結果在數據的排序字段值都相等時,輸出結果的順序就會因為N 值不同而不同。
SELECT *
FROM (SELECT ROWNUM r, a.*
FROM (SELECT name, g3e_fid FROM b$l_interest_info a ORDER BY name) a
WHERE ROWNUM <= 10)
WHERE r >= 1;
1 王家宅 55461079
2 王家宅 55461206
3 王家宅 55461207
4 王家宅 55461253
5 王家宅 55461246
6 王家宅 55461209
7 王家宅 55461783
8 王家宅 55461646
9 王家宅 55461586
10 王家宅 55461451
SELECT *
FROM (SELECT ROWNUM r, a.*
FROM (SELECT name, g3e_fid FROM b$l_interest_info a ORDER BY name) a
WHERE ROWNUM <= 20)
WHERE r >= 11;
11 王家宅 56990485
12 王家宅 56990368
13 王家宅 56981862
14 王家宅 56981861
15 王家宅 56981807
16 王家宅 56981806
17 王家宅 56981801
18 王家宅 55461646
19 王家宅 55461451
20 王家宅 55461209
解決辦法:
1、讓查詢計划避免“SORT (ORDER BY STOPKEY)”,采用“SORT (ORDER BY)”,使數
據排序不受ROWNUM 的影響。但這樣會使所有數據都做排序:
SELECT *
FROM (SELECT a.*, ROWNUM r
FROM (SELECT name, g3e_fid FROM b$l_interest_info a ORDER BY name) a)
WHERE r <= 10
AND r >= 1;
SELECT *
FROM (SELECT a.*, ROWNUM r
FROM (SELECT name, g3e_fid FROM b$l_interest_info a ORDER BY name) a)
WHERE r <= 20
AND r >= 11;
2、在排序時,加上一個或多個字段(如主鍵字段、ROWID),使排序結果具有唯一性:
SELECT *
FROM (SELECT ROWNUM r, a.*
FROM (SELECT name, g3e_fid FROM b$l_interest_info a ORDER BY name,g3e_fid) a
WHERE ROWNUM <= 10)
WHERE r >= 1;
SELECT *
FROM (SELECT ROWNUM r, a.*
FROM (SELECT name, g3e_fid FROM b$l_interest_info a ORDER BY name,g3e_fid) a
WHERE ROWNUM <= 20)
WHERE r >= 11;
3、對排序字段建立索引,並強制使用索引。這樣就能利用索引已經建立好的排序結果:
CREATE INDEX idx_b$l_interest_info_name ON b$l_interest_info(name);
ALTER INDEX idx_b$l_interest_info_name REBUILD;
SELECT *
FROM (SELECT ROWNUM r, a.*
FROM (SELECT /*+index(a idx_b$l_interest_info_name)*/
name, g3e_fid
FROM b$l_interest_info a
WHERE a.name IS NOT NULL
ORDER BY name) a
WHERE ROWNUM <= 10)
WHERE r >= 1;
SELECT *
FROM (SELECT ROWNUM r, b.*
FROM (SELECT /*+index(a idx_b$l_interest_info_name)*/
a.name, a.g3e_fid
FROM b$l_interest_info a
WHERE a.name IS NOT NULL
ORDER BY a.name) b
WHERE ROWNUM <= 20)
WHERE r >= 11;