达梦数据库分页用法
達(dá)夢(mèng)支持常用的分頁方式,ROWNUM(Oracle)、TOP(SQL Server)、LIMIT(MySQL)。
對(duì)于應(yīng)用提供了更好的可移植性。
數(shù)據(jù)準(zhǔn)備
| --創(chuàng)建學(xué)生表,id、姓名、年齡、成績 CREATE?TABLE?STU(id INT?,name varchar2(20),age int,score int); --插入100條數(shù)據(jù),id遞增,姓名DAMENG1遞增,年齡是13到17之前的隨機(jī)數(shù),成績是60到100之前的隨機(jī)數(shù) INSERT?INTO?STU SELECT?LEVEL?id,'DAMENG'||level?name,round(FLOOR(13 + (RAND()?* 5)))?age, round(FLOOR(60 + (RAND()?* 41)))?score FROM?DUAL ?CONNECT?BY?LEVEL<=100; commit; |
1.top
語法
| <TOP 子句>::=TOP <n> ????????????????????????| <n1>,<n2> ????????????????????????| <n> PERCENT ????????????????????????| <n> WITH TIES ????????????????????????| <n> PERCENT WITH TIES <n>::=整數(shù)(>=0) |
1. TOP <n> 選擇結(jié)果的前 n 條記錄;
2. TOP <n1>,<n2> 選擇第 n1 條記錄之后的 n2 條記錄;
3. TOP <n> PERCENT 表示選擇結(jié)果的前 n%條記錄;
4. TOP <n> PERCENT WITH TIES 表示選擇結(jié)果的前 n%條記錄,同時(shí)指定結(jié)果集可以返回額外的行。額外的行是指與最后一行以相同的排序鍵排序的所有行。WITH TIES
必須與 ORDER BY 子句同時(shí)出現(xiàn),如果沒有 ORDER BY 子句,則忽略 WITH TIES。
| select?top?5 * from?stu; |
| select?top?5,5 * from?stu; |
| select?top?5 percent?* from?stu; |
TOP <n> PERCENT WITH TIES表示選擇結(jié)果的前 n%條記錄,同時(shí)指定結(jié)果集可以返回額外的行。額外的行是指與最后一行以相同的排序鍵排序的所有行。WITH TIES必須與 ORDER BY 子句同時(shí)出現(xiàn),如果沒有 ORDER BY 子句,則忽略 WITH TIES。
其意思就是比如查詢按照成績?nèi)∏?%的學(xué)生,假如5%的學(xué)生的最后一位的成績是75,那么不在5%內(nèi)的成績是75的也查詢出來。
這個(gè)有啥實(shí)際意義呢,比如我要取5%的學(xué)生評(píng)為優(yōu)秀學(xué)生,假如最后一位是98分,那其他98分的學(xué)生也評(píng)為優(yōu)秀學(xué)生。
| select?top?5 percent??* from?stu order?by?score desc; select?top?5 percent?with?ties?* from?stu order?by?score desc; |
可以看到分?jǐn)?shù)98的學(xué)生都查詢出來了,多了兩條記錄。
可以使用存儲(chǔ)過程,實(shí)現(xiàn)每次查詢多少條數(shù)據(jù)
| create?or?replace?procedure?get_stuinfo(n int,m int)?as sqlstr varchar2(500); begin select?top?(n-1)*m,m * from?stu; end; / --需要?jiǎng)討B(tài)執(zhí)行 create?or?replace?procedure?get_stuinfo(n int,m int)?as sqlstr varchar2(500); begin sqlstr='select top '||(n-1)*m||','||m||' * from stu;'; execute?immediate?sqlstr; end; / call?get_stuinfo(1,5); |
2.limit
語法
| <LIMIT 子句>::=<LIMIT 子句 1> | <LIMIT 子句 2> <LIMIT 子句 1>::= ?LIMIT <記錄數(shù)> ??????????????????????????????????????????|<記錄數(shù)>,<記錄數(shù)> ??????????????????????????????????????????|<記錄數(shù)> OFFSET <偏移量> <LIMIT 子句 2>::= OFFSET <偏移量> LIMIT <記錄數(shù)> <記錄數(shù)>::=<整數(shù)> <偏移量>::=<整數(shù)> |
| select?* from?stu limit?5; select?* from?stu limit?5,10; select?* from?stu limit?10 OFFSET?5; select?* from?stu OFFSET?5 limit?10 ; |
可以看到后面三條語句的查詢結(jié)果相同。
3.rownum
達(dá)夢(mèng)有和oracle一樣的rownum的分頁功能。在對(duì)表進(jìn)行insert時(shí),會(huì)按照insert的順序,將rownum分配給每一行記錄,因此在select的時(shí)候,rownum的排序是根據(jù)insert記錄的順序顯示的。
| select?rownum,* ?from?stu; --可以看到rownum的順序與插入的順序是一致的。 select?rownum,* ?from?stu order?by?id desc; --可以看到即時(shí)是倒序查詢,rownum還是不變的。 |
對(duì)于多表查詢或者子查詢時(shí)候,rownum是根據(jù)查詢結(jié)果動(dòng)態(tài)分配的。
| select?rownum,?* ?from?stu t1,stu t2 where?t1.id=t2.id; |
如果查詢第一條記錄,可以使用rownum=1
| select?* from?stu where?rownum?=1; |
那如果查詢第二條記錄,是否可以通過rownum=2?
| select?* from?stu where?rownum?=2; |
可以看到?jīng)]有查詢結(jié)果。因?yàn)閞ownum并不是當(dāng)作實(shí)體數(shù)據(jù)存放在每一張表中,而是在每一次select查詢的時(shí)候,動(dòng)態(tài)分配的,有1才有2,如果rownum沒有1,那么2也就沒有了意義,所以這個(gè)查詢就不會(huì)有任何結(jié)果出來。同樣如果rownum>n 也是沒有意義的。
| select?rownum,* ?from?stu where?rownum?>0; select?rownum,* ?from?stu where?rownum?>=1; |
所以也就可以理解在rownum大于0或者大于等于1的時(shí)候,查詢出來的是所有結(jié)果。同時(shí)也可以進(jìn)一步想到,rownum>=n ?n是一個(gè)小于等于1的任何數(shù),都是返回所有結(jié)果。
n甚至可以是表達(dá)式。所以如果直接使用rownum>n,rownum<m分頁是無法查詢到結(jié)果的。
所以要使用rownum進(jìn)行分頁查詢,就需要使用子查詢,先將rownum查出來,把它當(dāng)做表中實(shí)際的列,進(jìn)行分頁。
| select?* from?(select?rownum?rn,* ?from?stu) where?rn >=1 and?rn<=5; |
總結(jié)
- 上一篇: VS在新建或者导入项目时出现“不支持此接
- 下一篇: 考勤月度统计mysql_mysql中跨月