达梦支持常用的分页方式,ROWNUM(Oracle)、TOP(SQL Server)、LIMIT(MySQL)。
对于应用提供了更好的可移植性。
数据准备
--创建学生表,id、姓名、年龄、成绩 CREATE TABLE STU(idINT ,namevarchar2(20),ageint,scoreint); --插入100条数据,id递增,姓名DAMENG1递增,年龄是13到17之前的随机数,成绩是60到100之前的随机数 INSERT INTO STUSELECT 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>::=整数(>=0) |
1. TOP <n> 选择结果的前 n 条记录;
2. TOP <n1>,<n2> 选择第 n1 条记录之后的 n2 条记录;
3. TOP <n> PERCENT 表示选择结果的前 n%条记录;
4. TOP <n> PERCENT WITH TIES 表示选择结果的前 n%条记录,同时指定结果集可以返回额外的行。额外的行是指与最后一行以相同的排序键排序的所有行。WITH TIES
必须与 ORDER BY 子句同时出现,如果没有 ORDER BY 子句,则忽略 WITH TIES。
select top 5 *from stu;
|
select top 5,5 *from stu;
|
select top 5percent *from stu;
|
TOP <n> PERCENT WITH TIES表示选择结果的前 n%条记录,同时指定结果集可以返回额外的行。额外的行是指与最后一行以相同的排序键排序的所有行。WITH TIES必须与 ORDER BY 子句同时出现,如果没有 ORDER BY 子句,则忽略 WITH TIES。
其意思就是比如查询按照成绩取前5%的学生,假如5%的学生的最后一位的成绩是75,那么不在5%内的成绩是75的也查询出来。
这个有啥实际意义呢,比如我要取5%的学生评为优秀学生,假如最后一位是98分,那其他98分的学生也评为优秀学生。
select top 5percent *from stuorder by scoredesc;
select top 5percent with ties *from stuorder by scoredesc;
|
可以看到分数98的学生都查询出来了,多了两条记录。
可以使用存储过程,实现每次查询多少条数据
create or replace procedure get_stuinfo(nint,mint) as sqlstrvarchar2(500); begin select top (n-1)*m,m *from stu; end; /
--需要动态执行 create or replace procedure get_stuinfo(nint,mint) as sqlstrvarchar2(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 <记录数> |<记录数>,<记录数> |<记录数> OFFSET <偏移量> <LIMIT 子句 2>::= OFFSET <偏移量> LIMIT <记录数> <记录数>::=<整数> <偏移量>::=<整数> |
select *from stulimit 5;
select *from stulimit 5,10;
select *from stulimit 10OFFSET 5;
select *from stuOFFSET 5limit 10;
|
可以看到后面三条语句的查询结果相同。
3.rownum
达梦有和oracle一样的rownum的分页功能。在对表进行insert时,会按照insert的顺序,将rownum分配给每一行记录,因此在select的时候,rownum的排序是根据insert记录的顺序显示的。
select rownum,* from stu;
--可以看到rownum的顺序与插入的顺序是一致的。 select rownum,* from stuorder by iddesc;
--可以看到即时是倒序查询,rownum还是不变的。 |
对于多表查询或者子查询时候,rownum是根据查询结果动态分配的。
select rownum, * from stu t1,stu t2where t1.id=t2.id;
|
如果查询第一条记录,可以使用rownum=1
select *from stuwhere rownum =1;
|
那如果查询第二条记录,是否可以通过rownum=2?
select *from stuwhere rownum =2;
|
可以看到没有查询结果。因为rownum并不是当作实体数据存放在每一张表中,而是在每一次select查询的时候,动态分配的,有1才有2,如果rownum没有1,那么2也就没有了意义,所以这个查询就不会有任何结果出来。同样如果rownum>n 也是没有意义的。
select rownum,* from stuwhere rownum >0; select rownum,* from stuwhere rownum >=1;
|
所以也就可以理解在rownum大于0或者大于等于1的时候,查询出来的是所有结果。同时也可以进一步想到,rownum>=n n是一个小于等于1的任何数,都是返回所有结果。
n甚至可以是表达式。所以如果直接使用rownum>n,rownum<m分页是无法查询到结果的。
所以要使用rownum进行分页查询,就需要使用子查询,先将rownum查出来,把它当做表中实际的列,进行分页。
select *from (select rownum rn,* from stu) where rn >=1and rn<=5;
|

















