SQL中获得序列的方法

这里说的“序列”不是 Oracle 中的 sequence ,而是产生一个从 n 到 m 的序列表,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
        SEQ
----------
          1
          2
          3
          4
          5
          6
          7
          8
          9
         10

序列表有什么用处呢,用处可大了,以后的文章中将大量用到。

我们先从产生 1 到 m 的序列表开始吧。

 

第一种做法是先建一个表,然后循环插入:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
create table t_seq
(
   seq int
);
  
declare 
   i number;
begin
   for i in 1..10 loop
     insert into t_seq values ( i );
   end loop;
   commit ;
end ;

这种做法的可移植性非常好,几乎任何数据库都可以使用,即使某些 DBMS 不支持 for 循环(例如SQL Server),完全可以借助其他循环语句例如 while 实施。

 

第二种,借助 rownum 伪列:

?
1
select rownum seq from user_objects where rownum<10;

通常我们借助一个记录比较多的系统表来获得 rownum 。

对于没有类似 rownum 这项功能的SQL Server,可以借助 identity 的递增来实现:

?
1
2
select seq=identity( int ,1,1) into #t from sys.objects ;
select seq from #t where seq<=10;

或者

?
1
2
select top 10 seq=identity( int ,1,1) into #t from sys.objects ;
select seq from #t;

或者借助分析函数 row_number() 实现:

?
1
select top 10 row_number() over ( order by object_id) from sys.objects;

当然实现的方式有很多,但是这种方法产生的序列受限于所借助的表,产生一个很大的序列就比较头痛了,而且产生I/O损耗是不可避免的。可以总结为直观,可移植性不佳。

 

第三种方法,递归查询,暂时发现能在 Oracle 10g 以上使用:

?
1
select level seq from dual connect by level <=10

这条语句一个 I/O 都不产生:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
------------------------------------------------------------------------------
| Id  | Operation                     | Name | Rows  | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |      |     1 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE               |      |     1 |            |          |
|   2 |   CONNECT BY WITHOUT FILTERING|      |       |            |          |
|   3 |    FAST DUAL                  |      |     1 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------
  
  
Statistics
----------------------------------------------------------
           0  recursive calls
           0  db block gets
           0  consistent gets
           0  physical reads
           0  redo size
         508  bytes sent via SQL*Net to client
         469  bytes received via SQL*Net from client
           2  SQL*Net roundtrips to/from client
           1  sorts (memory)
           0  sorts (disk)
           1  rows processed

该种方法对惜 I/O 如命,吹毛求疵者可谓居家旅行,清热解毒,杀人越货的必备良药 ^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值