oracle分頁查詢sql
『壹』 oracle做分頁查詢怎麼做
sql語句如下:
分頁1
SELECT *
FROM (Select ROWNUM AS ROWNO, T.*
from 表名 T(別名)
where 表欄位 between to_date('20060501', 'yyyymmdd') and to_date('20060731', 'yyyymmdd')
AND ROWNUM <= 20) TABLE_ALIAS
WHERE TABLE_ALIAS.ROWNO >= 10;
經過測試,此方法成本最低,只嵌套一層,速度最快,即使查詢的數據量再大,也幾乎不受影響,速度依然.
分頁2:
SELECT *
FROM (SELECT TT.*, ROWNUM AS ROWNO
FROM (Select t.*
from 表名 T(別名)
where flight_date between to_date('20060501', 'yyyymmdd') and
to_date('20060531', 'yyyymmdd')
ORDER BY FACT_UP_TIME, flight_no) TT(別名二)
WHERE ROWNUM <= 20) TABLE_ALIAS
where TABLE_ALIAS.rowno >= 10;
經過測試,此方法隨著查詢范圍的擴大,速度也會越來越慢,
『貳』 用SQL寫出分頁查詢
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A --不排序
WHERE ROWNUM <= 40
)
WHERE RN >= 21;
SELECT *
FROM (SELECT a.*, row_number() over(ORDER BY 1) rn--假排序,速度同上
FROM t1 a)
WHERE rn BETWEEN 21 AND 40;
SELECT *
FROM (SELECT a.*, row_number() over(ORDER BY c1) rn --真實排序,無法比較速度
FROM t1 a)
WHERE rn BETWEEN 21 AND 40;
Oracle的分頁查詢語句基本上可以按照本文給出的格式來進行套用。
分頁查詢格式:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21
其中最內層的查詢SELECT * FROM TABLE_NAME表示不進行翻頁的原始查詢語句。ROWNUM <= 40和RN >= 21控制分頁查詢的每頁的范圍。
上面給出的這個分頁查詢語句,在大多數情況擁有較高的效率。分頁的目的就是控制輸出結果集大小,將結果盡快的返回。在上面的分頁查詢語句中,這種考慮主要體現在WHERE ROWNUM <= 40這句上。
選擇第21 到40條記錄存在兩種方法,一種是上面例子中展示的在查詢的第二層通過ROWNUM <= 40來控制最大值,在查詢的最外層控制最小值。而另一種方式是去掉查詢第二層的WHERE ROWNUM <= 40語句,在查詢的最外層控制分頁的最小值和最大值。這是,查詢語句如下:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
)
WHERE RN BETWEEN 21 AND 40
對比這兩種寫法,絕大多數的情況下,第一個查詢的效率比第二個高得多。
這是由於CBO 優化模式下,Oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率。對於第一個查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內層查詢中,這樣Oracle查詢的結果一旦超過了ROWNUM限制條件,就終止查詢將結果返回了。
而第二個查詢語句,由於查詢條件BETWEEN 21 AND 40是存在於查詢的第三層,而Oracle無法將第三層的查詢條件推到最內層(即使推到最內層也沒有意義,因為最內層查詢不知道RN代表什麼)。因此,對於第二個查詢語句,Oracle最內層返回給中間層的是所有滿足條件的數據,而中間層返回給最外層的也是所有數據。數據的過濾在最外層完成,顯然這個效率要比第一個查詢低得多。
上面分析的查詢不僅僅是針對單表的簡單查詢,對於最內層查詢是復雜的多表聯合查詢或最內層查詢包含排序的情況一樣有效。
這里就不對包含排序的查詢進行說明了,下一篇文章會通過例子來詳細說明。下面簡單討論一下多表聯合的情況。對於最常見的等值表連接查詢,CBO 一般可能會採用兩種連接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低,一般CBO不會考慮)。在這里,由於使用了分頁,因此指定了一個返回的最大記錄數,NESTED LOOP在返回記錄數超過最大值時可以馬上停止並將結果返回給中間層,而HASH JOIN必須處理完所有結果集(MERGE JOIN也是)。那麼在大部分的情況下,對於分頁查詢選擇NESTED LOOP作為查詢的連接方法具有較高的效率(分頁查詢的時候絕大部分的情況是查詢前幾頁的數據,越靠後面的頁數訪問幾率越小)。
因此,如果不介意在系統中使用HINT的話,可以將分頁的查詢語句改寫為:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21
『叄』 oracle中要根據部門id分頁查詢Sql語句怎麼寫
oracle分頁有通用寫法,假設一頁5行
select * from (
select t.*,rownum from (
select * from table1 where condition order by column) t )
where rownum>(pangeNow-1)*5 and rownum<=(pageNow)*5
如果基礎查詢不需要排序,可以省掉一層嵌套
select * from (
select t.*,rownum from table1 t where condition )
where rownum>(pangeNow-1)*5 and rownum<=(pageNow)*5
『肆』 論述Oracle分頁查詢的幾種方式
sql語句如下:
分頁1
SELECT *
FROM (Select ROWNUM AS ROWNO, T.*
from 表名 T(別名)
where 表欄位 between to_date('20060501', 'yyyymmdd') and to_date('20060731', 'yyyymmdd')
AND ROWNUM <= 20) TABLE_ALIAS
WHERE TABLE_ALIAS.ROWNO >= 10;
經過測試,此方法成本最低,只嵌套一層,速度最快,即使查詢的數據量再大,也幾乎不受影響,速度依然.
分頁2:
SELECT *
FROM (SELECT TT.*, ROWNUM AS ROWNO
FROM (Select t.*
from 表名 T(別名)
where flight_date between to_date('20060501', 'yyyymmdd') and
to_date('20060531', 'yyyymmdd')
ORDER BY FACT_UP_TIME, flight_no) TT(別名二)
WHERE ROWNUM <= 20) TABLE_ALIAS
where TABLE_ALIAS.rowno >= 10;
經過測試,此方法隨著查詢范圍的擴大,速度也會越來越慢,
『伍』 實現oracle分頁的sql語句
下面是用ORACLE資料庫pl/sql編程實現的一個方式:
-------------------創建一個包--------------------------
create or replace package pages_query_pak as
type pages_cursor is ref cursor; --定一個游標,保存數據查詢得到的結果集
end pages_query_pak;
------------------創建一個過程----------------------
create or replace procere pages_pro(
tableName in varchar2,
pageSize in number,--每一頁顯示的記錄數
pageNow in number,--顯示第幾頁
myRows out number,--總記錄數
pageCount out number,--總頁數
page_cursor out pages_query_pak.pages_cursor--返回的記錄集 這里有用了上面那個包
) is
v_sql varchar2(1000);
v_begin number:=(pageNow-1)*pageSize+1;
v_end number:=pageNow*pageSize;
begin
v_sql:='select * from (select bt.*,rownum rnum from (select * from '|| tableName ||')bt
where rownum<='||v_end||') where rnum>='||v_begin;
open page_cursor for v_sql;
--計算myRows和pageCount
v_sql:='select count(*) from '||tableName;
execute immediate v_sql into myRows;
if mod(myRows,pageSize)=0 then
pageCount:=myRows/pageSize;
else
pageCount:=myRows/pageSize+1;
end if;
end;
『陸』 在oracle資料庫中的分頁SQL語句怎麼寫
前提:
分頁參數:size = 20 page = 2;
沒有order by的查詢;
嵌套子查詢,兩次篩選(推薦使用)。
SQL語句:
SELECT *
FROM (SELECT ROWNUM AS rowno, t.*
FROM DONORINFO t
WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
AND TO_DATE ('20060731', 'yyyymmdd')
AND ROWNUM <= 20*2) table_alias
WHERE table_alias.rowno > 20*(2-1);
(6)oracle分頁查詢sql擴展閱讀:
rownum總是從1開始的,第一條不滿足去掉的話,第二條的rownum 又成了1。依此類推,所以永遠沒有不滿足條件的記錄。
可以這樣理解:rownum是一個序列,是Oracle資料庫從數據文件或緩沖區中讀取數據的順序。它取得第一條記錄則rownum值為1,第二條為2。
依次類推:當使用「>、>=、=、between...and」這些條件時,從緩沖區或數據文件中得到的第一條記錄的rownum為1,不符合sql語句的條件,會被刪除,接著取下條。下條的rownum還會是1,又被刪除,依次類推,便沒有了數據。
『柒』 如何寫 oracle聯合查詢分頁的sql語句
oracle使用rownum偽列可以實現分頁,三表連接分頁示例代碼如下:
1
select * from (select rownum r,k.kch,k.kcm,cj.cj,x.xh,x.xm from KCB k,CJB cj,XSB x where k.kch = cj.kch and cj.xh = x.xh and rownum<=10) where r>0
特別注意這樣外層查詢時由於內層查詢的欄位有重復列名,所以內層查詢最後不要用*。取完每一個表欄位,這樣很容易報錯(「無效欄位」)
『捌』 oracle 分頁查詢 為什麼第一次子查詢用rownum,第二次用rn,其他方式都不可以呢
rownum 是一個虛列,不屬於表,只是用來給結果序號
要考慮結果邏輯。
比如我可以寫rownum>0或者rownum >= 1,查詢結果是全部結果
但是如果寫rownum > 1 結果就是空的。
解答:因為第一個結果rownum應該為1,不符合,所以排除
第二條,因為第一條被排除了,這一條應被安排在結果的第一個,rownum也應該排為1,所以不符合,排除
依次類推,全部都不符合,所以結果為空
而如果我將rownum作為一個臨時結果,再從這個臨時結果進行查詢,就可以使用這個值了
所以我們可以先成立一個臨時結果:select t1.*, rownum as "rn" from t1
然後從這個結果盡心查詢:select * from (select t1.*, rownum as "rn" from t1) where "rn" > 10 and "rn" <= 20
但是一般都會把小於等於放在第一個結果中,因為第一個結果是臨時的,會佔用內存,而且還不確定這個表的數據量具體有多大,所以,盡量減少臨時結果的大小,能起到增加效率的效果
select * from (select t1.*, rownum as "rn" from t1 where rownum <= 20) where "rn" > 10
註:你提到的rn,並不是一個固定值,而是臨時存放rownum的臨時結果的列,起了一個名字叫rn, 在欄位的後面,用[as 列名] 表示,也能用 [as "列名"]表示,語句當然可以寫成:select * from (select t1.*, rownum as aaa1234 from t1) where aaa1234 > 10 and aaa1234 <= 20;
別名的命名規則基本上是毫無顧忌的。只是如果不符合命名規則,比如數字開頭,擁有空格,運算符號,關鍵字 等情況的列名,需要用雙引號引起來,但是要注意,雙引號的列名,使用時也最好(非必須)用雙引號,因為系統執行sql語句時,會將沒有引號的字母全部翻譯成大寫,再執行,如果使用as "rn" ,然後使用rn查詢時,查詢語句中的rn會翻譯成RN,與欄位名的rn對應不上,報:找不到該欄位的錯誤。(當然,如果定義為 "RN",查詢語句中用rn 可以對應上,中文,大寫,符號,都無大小寫之分)
比如:
select * from (select t1.*, rownum as 1234 from t1) where 1234 > 10 and 1234 <= 20; 會報錯,因為1234不符合欄位命名規則
select * from (select t1.*, rownum as "1234" from t1) where 1234 > 10 and 1234 <= 20; 查詢為空,因為後一個1234會被認為是數字,而1234<= 20是一個恆false的條件
select * from (select t1.*, rownum as "1234" from t1) where "1234" > 10 and "1234" <= 20; 查詢結果正常
『玖』 oracle的實現分頁功能的sql語句該怎麼寫
這種好費勁啊
selectt.*
from
(selectsalgrade.*,row_number()over(orderbyGRADE)rnfromsalgrade)t
wheret.rnbetween1and10--這樣你可以查任意某幾行的數據,這個就是1-10行的
『拾』 初學oracle,怎樣寫一個oracle分頁sql語句
通過rownum來控制分頁,下面是sql語句:
select * from ( select row_.*, rownum rownum_ from (
select * from 表名 (where條件略)
) row_ where 最大行數 >= rownum )
where rownum_ > 最小行數
通過這條語句你可以看到,sql語句、最大行、最小行
1. sql控制要通過什麼樣的條件,來篩選出符合條件記錄,不多說了
2. 最大行數:你自己要計算的
3. 最小行數:也是你要計算的
比如:有150條記錄,每頁15條,通過計算共分為10頁。
第1頁:最小行數:(1-1)*10
最大行數:1*10;
第2頁:最小行數:(2-1)*10
最大行數:2*10
。。。。
第n頁:最小行數(n-1)*10
最大行數n*10
------------------------------------
僅供參考,不足之處,請多指教!