sql语句中限制结果集行数
在进行数据检索的时候有时候需要只检索结果集中的部分行,比如说“检索成绩排前三
名的学生”、“检索工资水平排在第3位到第7位的员工信息”,这种功能被称为“限制结果集
行数”。在虽然主流的数据库系统中都提供了限制结果集行数的方法,但是无论是语法还是
使用方式都存在着很大的差异,即使是同一个数据库系统的不同版本(比如MSSQLServer2000
和MSSQLServer2005)也存在着一定的差异。因此本节将按照数据库系统来讲解每种数据库
系统对限制结果集行数的特性支持。
1,Mysql
MYSQL中提供了LIMIT关键字用来限制返回的结果集,LIMIT放在SELECT语句的最后位置,
语法为“LIMIT 首行行号,要返回的结果集的最大数目”。比如下面的SQL语句将返回按照工
资降序排列的从第二行开始(行号从0开始)的最多五条记录:
SELECT * FROM T_Employee ORDER BY FSalary DESC LIMIT 2,5
2,Oracle
Oracle中支持窗口函数ROW_NUMBER(),其用法和MSSQLServer2005中相同,
ROW_NUMBER()函数可以计算每一行数据在结果集中的行号(从1开始计数),其使用语法
如下:
ROW_NUMBER OVER(排序规则)
比如我们执
行下面的SQL语句:
SELECT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY FSalary DESC) row_num, FNumber,FName,FSalary,FAge FROM T_Employee ) a WHERE a.row_num>=3 AND a.row_num<=5
Oracle支持标准的函数ROW_NUMBER(),不过Oracle中提供了更方便的特性用来计算行号,
也就在Oracle中可以无需自行计算行号,Oracle为每个结果集都增加了一个默认的表示行号
的列,这个列的名称为rownum。比如我们执行下面的SQL语句:
SELECT rownum,FNumber,FName,FSalary,FAge FROM T_Employee
使用rownum我们可以很轻松的取得结果集中前N条的数据行,比如我们执行下面的SQL
语句可以得到按工资从高到底排序的前6名员工的信息:
SELECT * FROM T_Employee WHERE rownum<=6 ORDER BY FSalary Desc
看到这里,您可能认为下面的SQL就可以非常容易的实现“按照工资从高到低的顺序取
出第三个到第五个员工信息”的功能了:
SELECT rownum,FNumber,FName,FSalary,FAge FROM T_Employee WHERE rownum BETWEEN 3 AND 5 ORDER BY FSalary DESC
执行完毕我们就能在输出结果中看到下面的执行结果:
ROWNUM FNUMBER FNAME FSALARY FAGE
检索结果为空!!!这非常出乎我们的意料。让我们来回顾一下rownum的含义:rownum
为结果集中每一行的行号(从1开始计数)。对于下面的SQL:
SELECT * FROM T_Employee WHERE rownum<=6 ORDER BY FSalary Desc
当进行检索的时候,对于第一条数据,其rownum为1,因为符合“WHERE rownum<=6”
所以被放到了检索结果中;当检索到第二条数据的时候,其rownum为2,因为符合“WHERE
rownum<=6”所以被放到了检索结果中……依次类推,直到第七行。所以这句SQL语句能够实
现“按照工资从高到低的顺序取出第三个到第五个员工信息”的功能。
而对于这句SQL语句:
SELECT rownum,FNumber,FName,FSalary,FAge FROM T_Employee WHERE rownum BETWEEN 3 AND 5 ORDER BY FSalary DESC
当进行检索的时候,对于第一条数据,其rownum为1,因为不符合“WHERE rownum
BETWEEN 3 AND 5”,所以没有被放到了检索结果中;当检索到第二条数据的时候,因为第
一条数据没有放到结果集中,所以第二条数据的rownum仍然为1,而不是我们想像的2,所以因
为不符合“WHERE rownum<=6”,没有被放到了检索结果中;当检索到第三条数据的时候,
因为第一、二条数据没有放到结果集中,所以第三条数据的rownum仍然为1,而不是我们想像
的3,所以因为不符合“WHERE rownum<=6”,没有被放到了检索结果中……依此类推,这样
所有的数据行都没有被放到结果集中。
因此如果要使用rownum来实现“按照工资从高到低的顺序取出第三个到第五个员工信息”
的功能,就必须借助于窗口函数ROW_NUMBER()。
3,MsSqlServer2000
MSSQLServer2000中提供了TOP关键字用来返回结果集中的前N条记录,其语法为
“SELECT TOP 限制结果集数目 字段列表 SELECT语句其余部分”,比如下面的SQL语句用来
检索工资水平排在前五位(按照工资从高到低)的员工信息:
select top 5 * from T_Employee order by FSalary Desc
MSSQLServer2000没有直接提供返回提供“检索从第5行开始的10条数据”、“检索第五行
至第十二行的数据”等这样的取区间范围的功能,不过可以采用其他方法来变通实现,最常
使用的方法就是用子查询
,比如要实现检索按照工资从高到低排序检索从第六名开始一共
三个人的信息,那么就可以首先将前五名的主键取出来,在检索的时候检索排除了这五名员
工的前三个人,SQL如下:
SELECT top 3 * FROM T_Employee WHERE FNumber NOT IN (SELECT TOP 5 FNumber FROM T_Employee ORDER BY FSalary DESC) ORDER BY FSalary DESC