JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Servlet/JSP 討論區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 大家是否可以提供 寫分頁的方式~ [精華]
823029





發文: 28
積分: 0
於 2003-09-09 08:14 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
如標題~

不好意思 現在有需要一個可以參考的分頁程式~或者物件

需要大家的幫忙 謝謝


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
snpshu

Norman

版主

發文: 1073
積分: 5
於 2003-09-09 09:08 user profilesend a private message to usersend email to snpshureply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
參考一下
http://www.javaworld.com.tw/jute/post/view?bid=6&id=1361&tpg=1&ppg=1&sty=1&age=0#1361

多利用search , 這一個站很多資源等你挖掘 Smile


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
browser

戀香

版主

發文: 3570
積分: 1
於 2003-09-09 10:18 user profilesend a private message to usersend email to browserreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=8893

各位高手們 .... 可以說一下你們的經驗嗎 ....

大家是徒手自行打造 ...
還是有發現到好用的 api or tag .....


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
java4by4





發文: 7
積分: 0
於 2003-09-10 14:39 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
原理如下:
將所有的資料先取出來,寫到檔案中,檔名用session id。
每一行一筆資料,然後呢,換頁就到該暫存檔中找,大
概這樣。
這是換了幾個寫法後,覺得比較好的,反正現在的硬碟
速度都不慢。
用cursor、物件存等,到流量大時,問題就來了。


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
prometheus

理智就像剝了皮的野獸



發文: 136
積分: 1
於 2003-09-13 02:18 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
用MySql的話直接用limit就搞定囉!!

reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
subbug



發文: 0
積分: 0
於 2003-09-13 03:32 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
823029你是施x昌嗎?我是吳xx耶,身為有身價的網頁工程師怎還沒接觸分頁功能?~~~

----------------------------------------------------------
  目前比较广泛使用的分页方式是将查询结果缓存在HttpSession或有状态bean中,翻页的时候从缓存中取出一页数据显示。这种方法有两个主要的缺点:一是用户可能看到的是过期数据;二是如果数据量非常大时第一次查询遍历结果集会耗费很长时间,并且缓存的数据也会占用大量内存,效率明显下降。
  其它常见的方法还有每次翻页都查询一次数据库,从ResultSet中只取出一页数据(使用rs.last();rs.getRow()获得总计录条数,使用rs.absolute()定位到本页起始记录)。这种方式在某些数据库(如oracle)的JDBC实现中差不多也是需要遍历所有记录,实验证明在记录数很大时速度非常慢。

  至于缓存结果集ResultSet的方法则完全是一种错误的做法。因为ResultSet在Statement或Connection关闭时也会被关闭,如果要使ResultSet有效势必长时间占用数据库连接。

  因此比较好的分页做法应该是每次翻页的时候只从数据库里检索页面大小的块区的数据。这样虽然每次翻页都需要查询数据库,但查询出的记录数很少,网络传输数据量不大,如果使用连接池更可以略过最耗时的建立数据库连接过程。而在数据库端有各种成熟的优化技术用于提高查询速度,比在应用服务器层做缓存有效多了。

评论人:mmgg 参与分: 24 专家分: 0 发表时间: 2003-9-12 下午4:44
evan,每次查询都要连接一次数据库是否影响效率,我看到的其他的代码大都是连接数据库后将连接放到session中,下次用的时候取出,不知道你是怎么考虑的?


subbug edited on 2003-09-13 03:56
reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
stallone_hwang





發文: 9
積分: 0
於 2003-09-26 15:59 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Dear ALL:
個人使用的是MS SQL2K DB,使用下列方式做分頁(12000筆巳上資料)

1
2
curpage=Integer.parseInt(request.getParameter("page"));//顯示的頁
ResultSet rs=cn.rsexecuteQuery("select top "+page_record+" * from tablename where id not in (select top "+(curpage*page_record)+" id from tablename order by id desc) order by id desc");


ps.這是利用MS SQL的Top,一次找還幾筆,loadind 在DB Server。目前使用上效果還不錯..
ps2.可否有更好的作法,例如可連各種DB,這樣就可寫一class大家用了..


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:stallone_hwang]
arthuroy





發文: 106
積分: 3
於 2003-09-28 16:23 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
以下是我在處理 Paging 時所參考到的資料,有興趣的可以看一看。
分頁不僅是在 JSP-based application 用的到,swing-based 也很需要呢。

# Jeremy Dickson. "Java Tip 137: Manage distributed JTables - Efficiently display huge JTables using distributed caching TableModels." JavaWorld. April 18, 2003.
http://www.javaworld.com/javatips/jw-javatip137_p.html

# Tim deBoer. "Displaying Tables in JavaServer Pages." IBM WebSphere Developer Domain. May 2000.
http://www7.software.ibm.com/vad.nsf/Data/Document2342?OpenDocument&p=1&BCT=66

# Java 訪問數據庫的速度瓶頸問題的分析及解決. IBM developerWorks 中國網站. November 2001. [GB2312]
http://www-900.ibm.com/developerWorks/cn/java/l-dbperform/index.shtml
--- comparison on Data Access Object (DAO), Fast Lane Reader (FLR), and Page-by-Page Iterator (PPI).

# 數據庫批量查詢分頁的完美解決之道. J 道論壇. 2002-09-26. [GB2312]
http://www.jdon.com:81/jive/thread.jsp?forum=16&thread=1591

# 用標準的 SQL 語句實現查詢記錄的分頁. JavaResearch Organization. 2002-09-05. [GB2312]
http://www.javaresearch.org/article/showarticle.jsp?column=108&thread=2028

# Ryan Brase. Deciding between iterators and lists for returned values in Java. August 14, 2002.
http://builder.com.com/article.jhtml?id=u00220020814R4B01.htm

# 查詢數據庫後是返回 ResultSet還是返回 Collection. J 道論壇. 2002-08-21. [GB2312]
http://www.jdon.com:81/jive/thread.jsp?forum=16&thread=302


reply to postreply to post
Self-Pity

I never saw a wild thing sorry for itself.
A small bird will drop frozen dead from a bough
without ever having felt sorry for itself.
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
gucci





發文: 98
積分: 0
於 2004-04-07 17:11 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
用MySql的話直接用limit

那oracle呢???


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:gucci]
systempanic





發文: 216
積分: 4
於 2004-04-07 20:01 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
gucci wrote:
用MySql的話直接用limit

那oracle呢???


用ROWNUM, for example:
1
2
select * from (select e.*, rownum rn from employee e where id=?) t 
where t.rn>= [startIndex] AND t.rn < [startIndex+_count];


摘錄自Bitter EJB, p.104


reply to postreply to post
NaN
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
gucci





發文: 98
積分: 0
於 2004-04-08 09:34 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我整理一下大家的討論
1. Oracle數據庫使用關鍵字:rowid或rownum
2. DB2:rowid或rownum ()
3. PostgreSQL 使用LIMIT 和 OFFSET
4. MySQL 使用Limit
5. MS SQL Server 沒有提供此技術

EX: oracle中,若只希望返回前十行紀錄
1
SELECT * FROM table WHERE ROWNUM<10; 


若是希望返回91-100筆紀錄
1
2
3
SELECT * FROM table WHERE ROWNUM<101; 
minus 
SELECT * FROM table WHERE ROWNUM<91;


那這樣的話
若我的db是採MS SQL
不就得一次把查詢的結果存到ResultSet嗎???
我有一個project
那樣的效能有點差說
有沒有什麼解決的辦法


gucci edited on 2004-04-08 09:44
reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
gucci





發文: 98
積分: 0
於 2004-04-08 09:58 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Q:如何使用rownum進行分頁?
A:
下面是我們單位開發人員提出的分頁方法:
「更為簡單、清晰的ORACLE分頁SQL:
1
select * from t_xxx where rownum < 201 minus select * from t_xxx where rownum < 101」

下面是我的回復:

這樣的SQL是令人擔憂的!

原因基於兩點:
1、我們知道rownum是oracle輸出結果中的虛行,即在實際的表中並沒有相應的存儲結構存在;
2、minus運算是在兩次操作結果的基礎上進行的,因此在非不得不的情況下,我們一貫主張避免使用類似的操作;

由此可以看出樓主提出的SQL:
1
select * from t_xxx where rownum < 201 minus select * from t_xxx where rownum < 101;

為了取出100條紀錄實際上執行了兩次SELECT共300條紀錄,舉個簡單的例子,如果共1000條紀錄,分頁為100條,那麼全部SELECT總數據量是
100+(200+100)+(300+200)+。。。
共是10000條,整整是10倍的數據量!如果是幾萬、幾十萬的數量級,再加上實際操作中的ORDER BY以及相關的WHERE條件,更不敢想像這樣SQL的效率。

在實際中針對分頁比較典型的做法是:
1
2
3
4
5
select * from 
( select rownum rnm, a.* from 
( select * from t where name=&myname order by name,dept) a 
where rownum <= &maxrnm ) 
where rnm >= &minrnm ; 


這裡有三個變量:
&myname where條件
&maxrnm要查詢的最大行號
&minrnm要查詢的最小行號

使用這樣的SQL在8i以後ORACLE是使用專門的優化來處理的,它需要排序字段預先建有索引,由於索引是已排序好的結構,因此取TOP n的問題,就變為從索引中直接從頭提取n個索引關鍵字,然後再根據索引就可快速的找到記錄並返回給用戶。從而有效避免了檢索全部記錄的情況。

按分頁計算,如果用戶很少瀏覽後面頁面的數據使用上面的SQL效率是很好,否則到某一刻index range scan所有滿足條件記錄時帶來的高成本,CBO甚至認為它高於FULL TABLE SCAN而選擇FULL TABLE SCAN。為了避免這一情況,針對經常需要瀏覽後面分頁數據的用戶,可以使用下面的SQL來處理:

1
2
3
4
5
6
7
select * from t where rowid in 
( select rid from 
( select rownum rno,rowid rid from 
( select rowid from t where name = &myname order by name,dept ) 
where rownum <= &maxrnm )
where rno >= &minrnm ) 
;


在這一方法中,我們考慮到索引與表相比,數據量大大小於後者,因此我們試圖先在索引中搜索出某頁記錄的物理位置,然後根據這些物理位置(rowid)在表中直接取出相應的記錄,這將有利消除上述FULL TABLE SCAN的出現。

當然二者之間的選擇要看我們的實際應用以及我們INDEX的情況,以便更好地提高效率。

另外一種做法在ORACLE8.1.6之後可以使用row_number() over()函數來實現:

1
2
3
select * from 
(SELECT owner,table_name,row_number() OVER(ORDER BY table_name) rownumber FROM dba_tables)
where rownumber >= 100 and rownumber <= 200; 

有人可以解釋一下上面這個SQL語法嗎?

引述自http://wolf-lab.com/cgi-bin/view.cgi?forum=13&topic=36


gucci edited on 2004-04-08 10:19
reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:arthuroy]
cherrie





發文: 2
積分: 0
於 2004-05-24 13:16 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這篇大家也可參考看看.
http://www.jdon.com/product/muiltipagequery.htm


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:cherrie]
arthuroy





發文: 106
積分: 3
於 2004-05-24 13:23 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
DisplayTag:

# Pageable DisplayTag with Hibernate by Xexex. April 29, 2004.

# htmltable 和 displaytag [本站精華]


arthuroy edited on 2004-05-24 13:27
reply to postreply to post
Self-Pity

I never saw a wild thing sorry for itself.
A small bird will drop frozen dead from a bough
without ever having felt sorry for itself.
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
lonely

JSP@ASIA.COM



發文: 69
積分: 0
於 2004-05-29 15:06 user profilesend a private message to usersend email to lonelyreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
PL-SQL 可使用 rownum 進行分頁。
T -SQL 可利用上頁的最後排序值以及 TOP 關鍵字。

另類做法,第一次捉資料時 把所要的資料全捉來放到 session 裡。
可以先放到 array 或 linklist 等元件裡,再放到 session。

然後看USER轉到第幾頁,再把 session 裡的資料拿出來、「切」出來 show 給 User 看 就好了。


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
lonely

JSP@ASIA.COM



發文: 69
積分: 0
於 2004-05-29 15:14 user profilesend a private message to usersend email to lonelyreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
講到效率 . . .
有時使用 PL-SQL 的 巢狀 Select 語法、 去繞出來所要的資料區段 . . . .
真是慢的可以 ~

T-SQL 的寫法 感覺好多了。


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
ROACH





發文: 64
積分: 0
於 2004-05-30 23:21 user profilesend a private message to usersend email to ROACHreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
想問一下啊
我公司是用as400的系統~應該是db2的資料庫

可是我發現他好像不支援TOP~ㄟ~
因為我直接在AS400打SQL語法~結果都不行

就連rowid()或rownum ()
也不支援~~

那還有什麼其他的~分頁方法ㄋ~

因為我現在是用rs.absolute()定位的方式~
但是總覺得好像很慢的樣子~


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
lonely

JSP@ASIA.COM



發文: 69
積分: 0
於 2004-05-31 00:25 user profilesend a private message to usersend email to lonelyreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
SQL 語法、講是講放諸四海而皆準啦 ~
當然這個 SQL 是指 SQL-92 而言 ( 是吧 !? )

各個 廠商可以再延伸
所以囉 有 PL-SQL T-SQL . . . .
TOP 這個是 T-SQL 的東西 適用於 MS$ 的產品、

DB2、IBM 的東西吧 ~ 當然 不見的用得上 !


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
lonely

JSP@ASIA.COM



發文: 69
積分: 0
於 2004-05-31 00:33 user profilesend a private message to usersend email to lonelyreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
rowid()、rownum ()
ORACLE 的東西 !

IBM 當然也不見得喜歡跟著別家廠商走 !

所以囉 ~ 各位程式師 才有的玩囉 !


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
paulma





發文: 76
積分: 5
於 2004-08-07 00:56 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
DB2 類似T-SQL 的TOP N 的用法如下, 請參考:
SELECT * FROM TABLENAME WHERE COL=VALUE FETCH FIRST N ROWS ONLY
N為任意數字


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:823029]
JackTasy





發文: 8
積分: 0
於 2004-08-09 18:16 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
提供一個經驗和想法給大家參考(不限資料庫種類):
1.若可以定義排序欄位的話最好
2.若沒有的話則利用 self join 技巧動態產生虛擬排序編號(就算資料庫沒有定義 PrimaryKey 一樣可以產生),然後分頁頁次用程式技巧可算出需取出虛擬編號起止號碼,然後加在 SQL where 即可。


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:JackTasy]
frank



版主

發文: 498
積分: 13
於 2004-08-10 16:46 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
JackTasy wrote:
2.若沒有的話則利用 self join 技巧動態產生虛擬排序編號(就算資料庫沒有定義 PrimaryKey 一樣可以產生),然後分頁頁次用程式技巧可算出需取出虛擬編號起止號碼,然後加在 SQL where 即可。

假設 RDBMS 提供類似 sequence (如 Oracle) 的方法當然是最方便的,
如無,據 JackTasy 兄的建議,
我試了下面的做法:
============================================
假設有個學生資料的 table 叫 student{id(PK), name, score},
欲將分數由高至低排序,取出第 11 至 20 名

1. 首先 self join 技巧動態產生虛擬排序編號
1
2
3
4
5
select count(*) as num, s1.id
from student s1, student s2
where s2.score >= s1.score
group by s1.id
order by num


2. 求得第 11 至 20 名之 id
1
2
3
4
5
6
7
8
9
10
select id 
from (
    select count(*) as num, s1.id
    from student s1, student s2
    where s2.score >= s1.score
    group by s1.id
    order by num;
) 
where num > 10
and num <= 20


3. 求得該 id 區間之資料
1
2
3
4
5
6
7
8
9
10
11
12
13
14
select * 
from student
where id in (
    select id 
    from (
        select count(*) as num, s1.id
        from student s1, student s2
        where s2.score >= s1.score
        group by s1.id
        order by num;
    ) 
    where num > 10
    and num <= 20
)

============================================
我分別透過 Aqua Data Studio 3.5 在 Oracle 9i 及 MySQL 上測試(皆為遠端主機, table 內約有 10k 筆資料),這樣子的確也可達到需求,
可是,在第一段 SQL 執行時,
Oracle 所花時間尚能接受,
MySQL performance 就差很多了

請問各位,上面的 SQL statement 該如何調整比較好?


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:frank]
frank



版主

發文: 498
積分: 13
於 2004-08-10 17:12 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
之前曾把 Hibernate 2.1.4 net.sf.hibernate.dialect package 中,支援之 Paged Queries 整理出來, post 在 Using Paged Queries in Variant RDBMS

這裡僅整理 Hibernate 2.1.4 使用之 SQL,供有需要的朋友參考:

分頁查詢語法
假設有個學生資料的 table 叫 student{id(PK), name, score},
若想依分數高低取出所有資料,我們會這麼下 SQL statement,
SELECT * FROM student ORDER BY score DESC
但是,若想取出
1. 分數排名在前 10 名的學生資料,
2. 分數排名在第 11 名至第 20 名間的學生資料,

在各個 DBMS 中,我們應如何下該 SQL 指令?
透過下面程式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.io.File;
import net.sf.hibernate.dialect.*;
 
public class HibernatePagingQueries {
 
    private static final String _package        = "net.sf.hibernate.dialect.";
    private static final String _querySelect    = "SELECT * FROM STUDENT ORDER BY SCORE";
    private static final int    _limit          = 10;
 
    private HibernatePagingQueries() { }
 
    private void checkLimitSupported(String dbDialect) {
        try {
            Dialect dialect = (Dialect)Class.forName(_package + dbDialect).newInstance();
 
            String myDbName = dbDialect.substring(0, dbDialect.indexOf("Dialect"));
            System.out.println(myDbName);
            if (dialect.supportsLimit()) {
                System.out.println("\t" + dialect.getLimitString(_querySelect, false, _limit));
                System.out.println("\t" + dialect.getLimitString(_querySelect, true,  _limit));
                System.out.println("\t" + dialect.getLimitString(_querySelect, false));
                System.out.println("\t" + dialect.getLimitString(_querySelect, true));
            } else {
                System.out.println("\t" + myDbName + " paged queries not supported");
            }
 
        } catch (ClassNotFoundException e) {
            System.out.println("ClassNotFoundException Occured when fileName = " + dbDialect);
        } catch (InstantiationException e) {
            System.out.println("InstantiationException Occured when fileName = " + dbDialect);
        } catch (IllegalAccessException e) {
            System.out.println("IllegalAccessException Occured when fileName = " + dbDialect);
        } catch (UnsupportedOperationException e) {
            System.out.println("UnsupportedOperationException Occured when fileName = " + dbDialect);
        }
    }
 
    public static void main(String[] args) {
        HibernatePagingQueries pagingqueries = new HibernatePagingQueries();
        String srcDirectory = "C:/hibernate-2.1/src/net/sf/hibernate/dialect";
        String[] files = new File(srcDirectory).list();
 
        for (int i = 0, len = files.length; i < len; i++) {
            if (!files[i].endsWith("Dialect.java")) {
                continue;
            }
            if (files[i].equals("Dialect.java")) { // IllegalAccessException, abstract class
                continue;
            }
 
            String fileName = files[i].substring(0, files[i].lastIndexOf("."));
            pagingqueries.checkLimitSupported(fileName);
 
        }
    }
 
}


可以得到下面的 SQL statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
DB2  
    1.1. SELECT * FROM STUDENT ORDER BY SCORE DESC fetch first 10 rows only
    1.2. select * from ( SELECT rownumber() over(ORDER BY SCORE DESC) as row_, * FROM STUDENT ORDER BY SCORE DESC ) as temp_ where row_ <= 10
    2.   select * from ( SELECT rownumber() over(ORDER BY SCORE DESC) as row_, * FROM STUDENT ORDER BY SCORE DESC ) as temp_ where row_ between 11 and 20
 
Firebird
    1. SELECT first 10 * FROM student ORDER BY score DESC
    2. SELECT first 10 SKIP 10 * FROM student ORDER BY score DESC
 
HypersonicSQL(HSQL)
    1. SELECT TOP 10 * FROM student ORDER BY score DESC
    2. SELECT LIMIT 10 10 FROM student ORDER BY score DESC
 
Interbase
    1. SELECT * FROM student ORDER BY score DESC ROWS 10
    2. SELECT * FROM student ORDER BY score DESC ROWS 10 TO 10
 
MySQL  
    1. SELECT * FROM student ORDER BY score DESC LIMIT 10
    2. SELECT * FROM student ORDER BY score DESC LIMIT 10, 10
 
Oracle  
    1. select * from ( SELECT * FROM STUDENT ORDER BY SCORE DESC ) where rownum <= 10
    2. select * from ( select row_.*, rownum rownum_ from ( SELECT * FROM STUDENT ORDER BY SCORE DESC ) row_ where rownum <= 10) where rownum_ > 20
 
PostgreSQL
    1. SELECT * FROM student ORDER BY score DESC limit 10
    2. SELECT * FROM student ORDER BY score DESC limit 10 OFFSET 10
 
SQLServer
    1. SELECT top 10 * FROM STUDENT ORDER BY SCORE DESC
 
paged queries not supported
FrontBase, Informix, Ingres, Mckoi, NoArgSQL, Pointbase, Progress, SAPDB, StandardSQL, Sysbase


HibernatePagingQueries.java (2.47k)


reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:frank]
JackTasy





發文: 8
積分: 0
於 2004-08-13 15:38 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
frank wrote:
假設 RDBMS 提供類似 sequence (如 Oracle) 的方法當然是最方便的,
如無,據 JackTasy 兄的建議,
我試了下面的做法:
============================================
假設有個學生資料的 table 叫 student{id(PK), name, score},
欲將分數由高至低排序,取出第 11 至 20 名

1. 首先 self join 技巧動態產生虛擬排序編號
1
2
3
4
5
select count(*) as num, s1.id
from student s1, student s2
where s2.score >= s1.score
group by s1.id
order by num


2. 求得第 11 至 20 名之 id
1
2
3
4
5
6
7
8
9
10
select id 
from (
    select count(*) as num, s1.id
    from student s1, student s2
    where s2.score >= s1.score
    group by s1.id
    order by num;
) 
where num > 10
and num <= 20


3. 求得該 id 區間之資料
1
2
3
4
5
6
7
8
9
10
11
12
13
14
select * 
from student
where id in (
    select id 
    from (
        select count(*) as num, s1.id
        from student s1, student s2
        where s2.score >= s1.score
        group by s1.id
        order by num;
    ) 
    where num > 10
    and num <= 20
)

============================================
我分別透過 Aqua Data Studio 3.5 在 Oracle 9i 及 MySQL 上測試(皆為遠端主機, table 內約有 10k 筆資料),這樣子的確也可達到需求,
可是,在第一段 SQL 執行時,
Oracle 所花時間尚能接受,
MySQL performance 就差很多了

請問各位,上面的 SQL statement 該如何調整比較好?


1.請教一下,你的 MySQL 是用哪一版的呢? 作業系統是...? 因為就我所知 MySQL 3.23-58 之前還無法支援 SubQuery 功能的喔,害我要寫一堆程式來克服,若新版可以的話我就可以更新嘍!
2.SubQuery 本來就是最耗資源的做法,據我的經驗尤其在 Oacle 8i 更是讓我望而怯步,很多地方寧願用程式來解決呢。
3.據我所知 SQL 指令動態產生虛擬欄位必須用 self join 不可,看來第一段可能別無他法...(但仍希望有其他 SQL 技巧解法..)|)


browser edited on 2004-08-13 15:48
reply to postreply to post
作者 Re:大家是否可以提供 寫分頁的方式~ [Re:JackTasy]
frank



版主

發文: 498
積分: 13
於 2004-08-13 16:06 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
JackTasy wrote:
MySQL 3.23-58 之前還無法支援 SubQuery 功能的喔,害我要寫一堆程式來克服,若新版可以的話我就可以更新嘍!

MySQL Manual 14.1.8 Subquery Syntax
1
2
3
Starting with MySQL 4.1, all subquery forms and operations 
that the SQL standard requires are supported, 
as well as a few features that are MySQL-specific.


reply to postreply to post
go to first page go to previous page  1   2  go to next page go to last page
» JWorld@TW »  Servlet/JSP 討論區

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8