bitsCN.com

数据库查询返回特定结果即分页查询

1 几种不同数据库的不同的分页写法:

a mysql

1

a) 查询前n条记录

2

select * from table_name limit 0,n

3

b) 查询第n条到第m条

4

select * from table_name limit n,m

b oracle

1

a)查询前n条记录

2

select * from table_name where rownum

3

b)查询第m条到第n条记录:

4

select * from (select a.*,a.rownum rn from table_name where rownumm

c sqlserver

1

a)查询前n条记录:

2

select top n * from table_name;

3

b)查询第n条到第m条记录:

4

select top n * from (select top m * from table_name order by column_name) a order by column_name desc

2 oracle rownum的用法

对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。

(1) rownum 对于等于某值的查询条件

如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。

SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)

(2)rownum对于大于某值的查询条件

如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录。

那如何才能找到第二行以后的记录呀。可以使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。

SQL>select * from(select rownum no ,id,name from student) where no>2;

(3)rownum对于小于某值的查询条件

如果想找到第三条记录以前的记录,当使用rownum1的自然数)的条件认为是成立的,所以可以找到记录。

SQL> select rownum,id,name from student where rownum

综上几种情况,可能有时候需要查询rownum在某区间的数据,那怎么办呀从上可以看出rownum对小于某值的查询条件是人为true的,rownum对于大于某值的查询条件直接认为是false的,但是可以间接的让它转为认为是true的。那就必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。

SQL> select * from (select rownum no,id,name from student where rownum=2;

(4)rownum和排序

Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。

SQL> select rownum ,id,name from student order by name;

可以看出,rownum并不是按照name列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。为了解决这个问题,必须使用子查询

SQL> select rownum ,id,name from (select * from student order by name);

3 mysql中的limit用法

具体的语法为:

1

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。

1

mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15

2

3

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:

4

mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

5

6

//如果只给定一个参数,它表示返回最大的记录行数目:

7

mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行

8

9

//换句话说,LIMIT n 等价于 LIMIT 0,n。

4 mysql的高效分页写法

1

Select a.* from (

2

select id from table b force index(ind_group_type_time)

3

where b.id=1111 order by b.update_time desc limit xx, xx

4

) b, table a where a.id=b.id;

MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要的,所以n越大,性能会越差。

优化前SQL: SELECT * FROM member ORDER BY last_active LIMIT 50,5

优化后SQL: SELECT * FROM member INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5) USING (member_id)

分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。

5 分页写法的页数计算

总页数=(总记录数-1)/每页显示的记录数 +1

总结一下:数据库中mysql和oracle的分页写法都不一致,各个数据库有各自的特点。另外要注意下相关sql的性能优化,特别是针对大数据的翻页查询。

bitsCN.com
09-05 06:55