1. Oracle常見SQL分頁實現方案
在Oracle中 用SQL來實現分頁有很多種實現方式 但有些語句可能並不是很通用 只能用在一些特殊場景之中
以下介紹三種比較通用的實現方案 在以下各種實現中 ROWNUM是一個最核心的關鍵詞 在查詢時他是一個虛擬的列 取值為 到記錄總數塵穗春的序號
首先來介紹我們工作中最常使用的一種實現方式
SELECT *
FROM (SELECT ROW_ * ROWNUM ROWNUM_
FROM (SELECT *
FROM TABLE
WHERE TABLE _ID = XX
ORDER BY GMT_CREATE DESC) ROW_
WHERE ROWNUM <= )
WHERE ROWNUM_ >= ;
其中最內層的查詢SELECT為不進行翻頁的原始查詢語句 可以用自己的任意Select SQL替換 ROWNUM <= 和ROWNUM >= 控制分頁查詢的每頁的范圍
分頁的目的就是控制輸出結果集大小 將結果盡快的返回 上面的SQL語句在大多數情況擁有較高的效率 主要體現在WHERE ROWNUM <= 這句上 這樣就控制了查詢過程中的最大記錄數
上面例子中展示的在查詢的第二層通過ROWNUM <= 來控制最大值 在查詢的最外層控制最小值 而另一種方式是去掉查詢第二層的WHERE ROWNUM <= 語句 在查詢的最外層控制分頁的最小值和最大值 此時SQL語句如下 也就是要介紹的第二種實現方式
SELECT *
FROM (SELECT A * ROWNUM RN
FROM (SELECT *
FROM TABLE
WHERE TABLE _ID = XX
ORDER BY GMT_CREATE DESC) A)
WHERE RN BEEEN AND ;
由於Oracle可以將外層的查詢條件推到內層查詢中 以提高內層查詢的執行效率 但不能跨越多層
對於第一個查詢語句派耐 第二層的查詢條件WHERE ROWNUM <= 就可以被Oracle推入到內層查詢中 這樣Oracle查詢的結果一旦超過了ROWNUM限制條件 就終止查詢將結果返回了
而 第二個查詢語句 由於查詢條件BEEEN AND 是存在於查詢的第三層 而Oracle無法將第三層的查詢條件推到最內層(即使推到最內層也沒有意義 因為最內層查詢不知道RN代表什麼) 因此 對於第二個查詢語句 Oracle最內層返回給中間層的是所有滿足條件的數據 而中間層返回給最外層的也是所有數據 數據的過濾在最外層完成 顯然這個效率要比第一個查詢低得多
以上兩種方案完全是通過ROWNUM來完成 下面一種則採用ROWID和ROWNUM相結合的方式 SQL語句如下
SELECT *
FROM (SELECT RID
FROM (SELECT R RID ROWNUM LINENUM
FROM (SELECT ROWID RID
FROM TABLE
WHERE TABLE _ID = XX
ORDER BY GMT_CREATE DESC) R
WHERE ROWNUM <= )
WHERE LINENUM >= ) T
TABLE T
WHERE T RID = T ROWID;
從語句上看 共有 層Select嵌套查詢 最內層為可替換的不分頁原始SQL語句 但是他查詢的欄位只有ROWID 而沒有任何待查詢的實際表欄位 具體查詢實際欄位值是在最外層實現的
這種方式的原理大致為 首先通過ROWNUM查詢到分頁之後的 條實際返回記錄的ROWID 最後通過ROWID將最終返回欄位值查詢出來並返回
和前面兩種實現方式相比 該SQL的實現方式更加繁瑣 通用性也不是非常好 因為要將原始的查詢語句分成兩部分(查詢欄位在最外層 表及其查詢條件在最內層)
但這種實現在特定場景下還是有優勢的 比如我們經常要翻頁到很後面 比如 條記錄中我們族弊經常需要查 及其以後的數據 此時該方案效率可能要比前面的高
因為前面的方案中是通過ROWNUM <= 來控制的 這樣就需要查詢出 條數據 然後取最後 之間的數據 而這個方案直接通過ROWID取需要的那 條數據
從不斷向後翻頁這個角度來看 第一種實現方案的成本會越來越高 基本上是線性增長 而第三種方案的成本則不會像前者那樣快速 他的增長只體現在通過查詢條件讀取ROWID的部分
當然 除了以上提了這些方案 我們還可以用以下的SQL來實現
SELECT *
FROM TABLE
WHERE TABLE _ID NOT IN
(SELECT TABLE _ID FROM TABLE WHERE ROWNUM <= )
AND ROWNUM <= ;
SELECT *
FROM TABLE
WHERE ROWNUM <=
MINUS
SELECT * FROM TABLE WHERE ROWNUM <= ;
………………
注意 當ROWNUM作為查詢條件時 他是在order by之前執行 所以要特別小心
比如我們想查詢TABLE 中按TABLE _ID倒序排列的前 條記錄不能用如下的SQL來完成
lishixin/Article/program/Oracle/201311/11198
2. 求助大神Oracle分頁
分頁的SQL語句
如果我們是通過JDBC的方式訪問資料庫,那麼就有必要根據資料庫類型採取不同的SQL分頁語句,對於MySQL資料庫,我們可以採用limit語句進行分頁,對於Oracle資料庫,我們可以採用rownum的方式進行分頁.
(1)MySql的Limit m,n語句
Limit後的兩個參數中,參數m是起始下標,它從0開始;參數n是返回的記錄數。我們需要分頁的話指定這兩個值即可
(2)Oracle資料庫的rownum
在Oracle資料庫中,分頁方式沒有MySql這樣簡單攜猜,它需要依靠rownum來實現.
Rownum表示一條記錄的行號,值得注意的是它在獲取每一行後才賦予.因此,想指定rownum的區間來取得分頁數據在一層查詢語句中是無法做到的,要分頁還要進行一次查詢.
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最內層返回給中間層的是所有滿足條件的數據,而中間層返回給最外層的也是所有數據。數據的過濾在最外層完成,顯然這個效率要比第一個查詢低得多。
上面分析的查詢不僅僅是針對單表的簡單查詢,對於最內層查詢是復雜的多表聯合查詢或最內層查詢包含排序的情況一樣有效。
附:分頁技術實現:http: //www. blogjava.net/sitinspring/archive/2008/09/13/228771. html
附:Oracle分頁查詢:http://yangtingkun.itpub.net/post/468/109834
附:使用 PHP 和 Oracle 實施分頁結果集:http: //www. oracle.com/technology/global/cn/pub/articles/oracle_php_cookbook/fuecks_paged. html
其實分頁技術還有很多其它技術,比如:Struts、hibernate等等都可實現。
3. 在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);
(3)oracle資料庫分頁擴展閱讀:
rownum總是從1開始的,第一頃困條不滿足去掉的話,第二條的rownum 又成了1。依此類推,所以永遠沒有不滿足條件的記錄。
可以這樣理解:rownum是一個序列,是Oracle資料庫從數據文件或緩沖區中讀取數據的順序。它取得第散春一條記錄則rownum值為1,第二條為2。
依次類推:當使用「>、>=、=、between...and」這些條件時,從緩沖雀掘念區或數據文件中得到的第一條記錄的rownum為1,不符合sql語句的條件,會被刪除,接著取下條。下條的rownum還會是1,又被刪除,依次類推,便沒有了數據。
4. Oracle資料庫中如何快速查詢分頁
SELECTB.*FROM(SELECTA.*,ROWNUMRNFROM(
SELECTt.欄位1,
t.欄位2,
t.欄位3,
t.欄位4,
t.欄位5
FROM表Tablet
WHERE1=1
--這里可以加其他條件
ORDERBY需要排序欄位DESC
)A)BWHERERN<=(#page#*#rows#)ANDRN>(#page#-1)*#rows#
#page#頁碼(第幾頁)
#row#每頁顯示條數
5. oracle怎麼實現分頁
因為Oracle資料庫沒有Top關鍵字,所以這里就不能夠像微軟的數據據那樣操作,這里有兩種方法:
一種是利用相反的。
PAGESIZE:每頁顯示的記錄數
CURRENTPAGE:當前頁號
數據表的名字是:components
索引主鍵字是:id
select * from components where id not in(select id from components where rownum<=(PAGESIZE*(CURRENTPAGE-1))) and rownum<=PAGESIZE order by id;
如下例:
select * from components where id not in(select id from components where rownum<=100) and rownum<=10 order by id;
從101到記錄開始選擇,選擇前面10條。
使用minus,即中文的意思就是減去,呵呵,這語句非常的有意思,也非常好記
select * from components where rownum<=(PAGESIZE*(CURRENTPAGE-1)) minus select * from components where rownum<=(PAGESIZE*(CURRENTPAGE-2));
如例:select * from components where rownum<=10 minus select * from
一種是利用Oracle的rownum,這個是Oracle查詢自動返回的序號,一般不顯示,但是可以通過select rownum from [表名],可以看到,是從1到當前的記錄總數。
select * from (select rownum tid,components.* from components where rownum<=100) where tid<=10;
6. Oracle之分頁
在Oracle中有一個方法rownum用來查詢第一行到第n行的內容,但沒有一個合適的方法若查詢第x行到第y行的內容,而在實際應用中卻經常需要查詢第x行到第y行的內容,這時我們就需要使用rownum和子表查詢等內容來進行查詢,因為這一塊內容屬於Oracle總的常用部分所以專門或裂搏在此介紹。
在Oralce中有一個偽列rownum,其在創建表的時候就存在了卻不顯示,若要使用這個列可以直接調用即可,也可以對這個列添加別名源凳來調用。
rownum只能用於顯示小於某行的數據即第一行開始到你要查詢到的那一行為止的數據。
在Oracle把查詢第幾行到第幾行的操作稱為分頁,其具體操作是通過子查詢等操作完成。
select 列名 from (select 表名.*,rownum rn from 表名)表名 where rn操作;
思考如下:
1.選擇所有內容
select * from emp;
2.顯示rownum
select e.*,rownum rn from(select * from emp)e;
這一步可以精簡為下面形式,但某些情況只能用上面那種
select emp.*,rownum rn from emp;
3.查詢
select * from(select e.*,rownum rn from (select * from emp)e);
4.其他變化
在某些時候我們需要先對表的內容進行排序,隨後查詢第x行到第y行的內容,這個時候有一個需要注意的點是rownum是在表產生的時候產生的偽列,所以使用排序會連著rownum的值進行排序,從而達不到想要的效果。
為了解決上述這個問題,我們需要使用子表查詢即先排好序,再在新表之中顯示衫祥rownum來規避這個問題。
考慮到排序的問題,所以在上方第二步的時候使用第一種方法即select e.*,rownum rn from(select * from emp)e;,在內表select * from emp中進行排序可以完成在亂序中找到第x行到第y行的效果。
7. oracle分頁 語句
對的,你說的對,鋒源扒但是rowCount 不行吧,我一直用rownum,是了一下rowCount也銀昌不行,但是建議你這樣寫:
select /*+first_rows(10)*/ b.* from
(select /*+first_rows(10)*/ a.*,rownum rnum from
(select /*+first_rows(10)*/ * from student ) a where rownum<= "+currentPage*pageSize+"
)b
where rnum>= (currentPage-1)*pageSize;
這個意思就是認為的在sql中添裂中加hint 資料庫返回指定條目的數據是最快的。
8. 使用三層嵌套正確實現Oracle分頁
原始記錄
select t * t rowid from t_stu t
order by t s_birthday desc
返回
STU_ID S_NAME C_ID S_BIRTHDAY
S 李四 C
S 張 C
S 張 C
S 張 山兄 C
S 張 C
Oracle分頁查詢
第一種 兩層嵌套查詢(網上流行的一種錯誤)
select * from
(
select rownum r t * from t_stu t
)
where r beeen and order by s_birthday desc
返回
R STU_ID S_NAME C_ID S_BIRTHDAY
S 李四 C
S 張三豐好漏 C
S 張三 C
說明 上面的結果可能與你的不一樣 因為Oracle在沒有order by的情況 是隨機選取記錄的 前 名的記錄應該是
STU_ID S_NAME C_ID S_BIRTHDAY
S 李四 C
S 張 C
S 張 C
第二種 換用三層嵌套查詢
select b * from
(select rownum r a * from
(select t * from t_stu t order by s_birthday desc )a
)b
where b r beeen and
返回
R STU_ID S_NAME C_ID S_BIRTHDAY
S 李四 C
S 張 C
S 張 C
正確!
所以Oracle分布查詢一定要用三層嵌套 步驟如下
第三層 分頁過濾
select b *
from (
逗襪襲 第二層 給定行號
select rownum r a * from (
第一層 排序
select * from 表 order by 欄位
) a
where rownum<=最大行
)b
where b r beeen 最小行 and 最大行
關鍵點 先排序 後給行號 兩個步驟要分開!
為了程序的通用性 對任意數據集都能分頁 利用子查詢改為如下結構
第三層 分頁過濾
select b *
from (
第二層 給定行號
select rownum r a * from (
第一層 排序
select * from (一個已經排序的數據集)
) a
where rownum<=最大行
)b
where b r beeen 最小行 and 最大行
如上面的查詢改為
第三層 分頁過濾
select b *
from (
第二層 給定行號
select rownum r a * from (
第一層 排序
select * from (select t * from t_stu t order by s_birthday desc)
) a
where rownum<=最大行
)b
where b r beeen 最小行 and 最大行
或者其它查詢語句
第三層 分頁過濾
select b *
from (
第二層 給定行號
select rownum r a * from (
第一層 排序
select * from (select t * from 新聞表 t order by 發貼日期 desc)
) a
where rownum<=最大行
)b
where b r beeen 最小行 and 最大行
原始數據數據腳本(請在命令窗口中粘貼以下語句即可)
prompt PL/SQL Developer import file
prompt Created on 年 月 日 星期一 by Administrator
set feedback off
set define off
prompt Dropping T_STU
drop table T_STU cascade constraints;
prompt Creating T_STU
create table T_STU
(
STU_ID CHAR( )
S_NAME CHAR( )
C_ID CHAR( )
S_BIRTHDAY DATE
S_SEX CHAR( )
)
;
prompt Disabling triggers for T_STU
alter table T_STU disable all triggers;
prompt Loading T_STU
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張三 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 李四 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張三豐 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)
values ( S 張 C to_date( dd mm yyyy ) null);
mit;
prompt records loaded
prompt Enabling triggers for T_STU
alter table T_STU enable all triggers;
set feedback on
set define on
lishixin/Article/program/Oracle/201311/18196
9. oracle資料庫怎麼實現分頁,且每頁三條數據
您好:oracle查詢分頁可分為兩種情況,一種使用的是rownum ,另外一種則是使用 row_number() over(order by column_name desc)。
1.使用rownum分頁查詢,可用以下方式:
select t2.* from (select t1.*,rownum as rn from table_name t1 where 1=1 and rownum <= page * page_size) t2 where t2.rn > (page - 1) * page_size;
2.使用 row_number() over() 分頁查詢
select t2.* from (select t1.*,row_number() over(order by column_name desc) as rn from table_name t1 where 1=1 )t2 where t2.rn > (page-1)* page_size and t2.rn <= page * page_size;
這種方式,也是可以分頁的。
希望能幫助您!
10. 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;
經過測試,此方法隨著查詢范圍的擴大,速度也會越來越慢,