当前位置: 代码迷 >> SQL >> sql话语中限制结果集行数
  详细解决方案

sql话语中限制结果集行数

热度:17   发布时间:2016-05-05 13:24:06.0
sql语句中限制结果集行数

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  

?

  相关解决方案