Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1477796
  • 博文数量: 187
  • 博客积分: 10375
  • 博客等级: 上将
  • 技术积分: 3127
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-07 10:58
文章分类

全部博文(187)

文章存档

2013年(1)

2012年(8)

2011年(28)

2010年(36)

2009年(47)

2008年(67)

我的朋友

分类: Oracle

2008-11-15 22:41:14

    今天去一家公司笔试时,又遇到了一道以前曾遇到过的SQL题,是这样的:
    如果想从一个表中以某一字段排序后,取得除了20-30行以外的记录,写一条SQL来实现。
 
    想到了用rownum,oracle专用的一个伪列。当时写的有点问题,回来后试了一下,不行!
 
    于是重新在网上查了一下,下面是基本的实现:
    假设表结构如下:
 
    Student(sid, sname, age)
 
    SQL:以sid升序排序

select * from
(select a.*, rownum rn from

    (select * from strdent order by sid ) a

)
where
rn < 20 or rn > 30;

    如果分页时,想取得第20-30条记录可以用以下的方法:

select * from
(select a.*, rownum rn from

    (select * from strdent order by sid ) a where rownum <= 30

)
where rn >= 20;

    这里有一点需要说明,在最内层的查询中,因为是全部的记录,所以在这次查询排序后,每条记录的rownum已经确定,并在第二层的查询中将它作为一个字段记录下来,在最外层的条件中使用。就是说在查询结果中,必须以第一次排序查询时的rownum为基准,统一使用这时候的rownum值,结果才是正确的。如果在第二次加上条件后的查询结果,它还会有一个rownum,但是它的值已经变了,如果用这个值,那么结果也就不是我们想要的了。

    Oracle的rownum字段是个比较奇怪的字段。拿一张有26条记录的Test表来举例。
     select * from Test where rownum >=1;
     select * from Test where rownum >=2;
     select * from Test where rownum <= 10;
    第一条sql查出了26条记录,第二条sql一条记录也没查出。第三条sql查出10条记录。

    导致这个的原因是因为rownum是个虚拟的字段,它是在记录输出的时候逐步产生的

    对第一条sql,第一条记录的rownum是1,满足条件被输出,因此第二条纪录的rownum就变成2,满足条件被输出,依此类推,就把所有纪录都查出来了。
    对于第二条sql,第一条记录的rownum是1,不满足条件没被输出,因此第二条记录的rownum还是1,没满足条件没被输出,依此类推,所有纪录都没能被查出来。

 
   
阅读(997) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-11-19 10:01:34

呵呵,又学到了。以后多些我也好学学。