MS SQLSERVER和ORACLE中取出表中按照某字段排序的前N條記錄<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
這個題目看上去似乎那麼簡單, 兩種數據庫都提供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
歡迎交流,轉貼請保留以上信息