先排序还是先取值

** ** ** 先排序还是先取值 ** ** **

** 题目 ** ** : MS SQLSERVER ** ** 和 ** ** ORACLE ** ** 中取出表中按照某字段排序的前 ** ** N ** ** 条记录 ** ** **

这个题目看上去似乎那么简单 , 两种数据库都提供 ORDER BY 子句 . 问题应该能够迎刃而解吧 .

先试一下 MS SQLSERVER 是怎么做的 :

use Northwind;

create table TestSort (ID integer);

insert into testSort values (3);

insert into testSort values (1);

insert into testSort values (4);

insert into testSort values (2);

select * from testSort;

-----------------------------------------

ID

-----------

3

1

4

2

(4 row(s) affected)

假设我们要取出按照 ID 排序的前三条记录 :

select TOP 3 * from testSort order by ID ;

-----------------------------------------

ID

-----------

1

2

3

(3 row(s) affected)

很简单 , 一句话就解决了 .

再试一下 ORACLE ( 这里用 ORACLE9i)

SQL> create table TestSort ( ID number);

Table created.

SQL> insert into testSort values (3);

1 row created.

SQL> insert into testSort values (1);

1 row created.

SQL> insert into testSort values (4);

1 row created.

SQL> insert into testSort values (2);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from testSort;

ID

----------

3

1

4

2

ORACLE 没有 MS SQLSERVER 中取前 N 条记录的 TOP 语法 . 但是有 ROWNUM 可以用来完成类似功能 .

SQL> select * from TestSort where rownum <= 3 order by ID;

ID

----------

1

3

4

结果是不是有点出乎意料 ? 它并没有返回所要求的 1 , 2 , 3 的结果 . ORACLE 先根据 rownum <=3 的条件限制选取一个范围集合 (3,1,4), 然后再在这个集合里进行排序 .

ORDER BY 子句是在合适的记录被取出后才起作用 .

原来如此 , 那么在 ORACLE 中如何才能实现这个功能呢 ?

通常我们可以采用这种办法 :

** SQL> select * from (select * from TestSort order by ID) where rownum <=3; **

ID

----------

1

2

3

有点麻烦 , 不过也只能这样 .

相同道理 , 如果想从表中取出按照某字段排序前 M 到 N 条记录

下面的 ORACLE 语句是最好的 :

SQL> select ID from

(

select ID , rownum as con from

(

select ID from TestSort order by ID

)

** where rownum <= 3 /*N ** ** 值 ** ** */ **

)

** where con >= 2; /*M ** ** 值 ** ** */ **

ID

----------

2

3

MS SQLSERVER 中也可以用类似的思路解决此类问题 .

当然你也可以用笨一点的办法 , 比如用前 N 条记录的集合 MINUS 前 M-1 条记录的集合得到

前 M 到 N 条记录集合 . ( 有点象饶口令 ) , 不过 MS SQLSERVER 好象不支持 MINUS 之类的集合操作 .

看来小小的一个排序取值问题还真不是那么简单呢 !

Black_Snail

[email protected]

欢迎交流 , 转贴请保留以上信息

Published At
Categories with 数据库类
comments powered by Disqus