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  

猜你喜欢

转载自honly-java.iteye.com/blog/1632872