A. oracle怎麼實現多表 連接查詢 並分頁。。。
oracle使用rownum偽列可以實現分頁,三表連接分頁示例代碼如下:
select*from(selectrownumr,k.kch,k.kcm,cj.cj,x.xh,x.xmfromKCBk,CJBcj,XSBxwherek.kch=cj.kchandcj.xh=x.xhandrownum<=10)wherer>0
特別注意這樣外層查詢時由於內層查詢的欄位有重復列名,所以內層查詢最後不要用*。取完每一個表欄位,這樣很容易報錯(「無效欄位」)
B. 如何實現Oracle資料庫的分頁顯示
1.使用T_BASE_PROVINCE表作為測試演示使用
C. 使用三層嵌套正確實現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
D. 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
E. oracle 資料庫中 如何分頁
下面兩種用可以用rownum的變通方式實現分頁:
select
*
from
(select
rownum
row_num,month,sell
from
(select
month,sell
from
sale
group
by
month,sell)
)
where
row_num
between
5
and
9;【網友評論】
select
dmp.row_num,dmp.requirement_id
from
(select
rownum
as
row_num,
requirement_id
from
(select
requirement_id
from
requirement
order
by
requirement_id
desc)
)
dmp
where
row_num
between
10
and
20;【網友評論】
F. 求一個通用ORACLE存儲過程,實現分頁和查詢
create
or
replace
package
Tools
is
type
ResultData
is
ref
cursor;
procere
sp_Page(p_PageSize
int,
--每頁記錄數
p_PageNo
int,
--當前頁碼,從
1
開始
p_SqlSelect
varchar2,
--查詢語句,含排序部分
p_SqlCount
varchar2,
--獲取記錄總數的查詢語句
p_OutRecordCount
out
int,--返回總記錄數
p_OutCursor
out
ResultData);
end
Tools;
create
or
replace
package
body
Tools
is
procere
sp_Page(p_PageSize
int,
--每頁記錄數
p_PageNo
int,
--當前頁碼,從
1
開始
p_SqlSelect
varchar2,
--查詢語句,含排序部分
p_SqlCount
varchar2,
--獲取記錄總數的查詢語句
p_OutRecordCount
out
int,--返回總記錄數
p_OutCursor
out
ResultData)
as
v_sql
varchar2(3000);
v_count
int;
v_heiRownum
int;
v_lowRownum
int;
begin
----取記錄總數
execute
immediate
p_SqlCount
into
v_count;
p_OutRecordCount
:=
v_count;
----執行分頁查詢
v_heiRownum
:=
p_PageNo
*
p_PageSize;
v_lowRownum
:=
v_heiRownum
-
p_PageSize
+1;
v_sql
:=
'SELECT
*
FROM
(
SELECT
A.*,
rownum
rn
FROM
('||
p_SqlSelect
||')
A
WHERE
rownum
<=
'||
to_char(v_heiRownum)
||
'
)
B
WHERE
rn
>=
'
||
to_char(v_lowRownum)
;
--注意對rownum別名的使用,第一次直接用rownum,第二次一定要用別名rn
OPEN
p_OutCursor
FOR
v_sql;
end
sp_Page;
end
Tools;
G. 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 資料庫返回指定條目的數據是最快的。
H. Oracle資料庫中如何快速查詢分頁
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;
I. 在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);
(9)oracle資料庫實現分頁擴展閱讀:
rownum總是從1開始的,第一條不滿足去掉的話,第二條的rownum 又成了1。依此類推,所以永遠沒有不滿足條件的記錄。
可以這樣理解:rownum是一個序列,是Oracle資料庫從數據文件或緩沖區中讀取數據的順序。它取得第一條記錄則rownum值為1,第二條為2。
依次類推:當使用「>、>=、=、between...and」這些條件時,從緩沖區或數據文件中得到的第一條記錄的rownum為1,不符合sql語句的條件,會被刪除,接著取下條。下條的rownum還會是1,又被刪除,依次類推,便沒有了數據。
J. 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;