2013-06-22 90 views
0

ROWNUM我haae这个怪癖与ROWNUM:麻烦与查询

select rownum as n, s.* from vzwnet.site_inst s where n between 2 and 10 --> dones not work 

我必须把它作为:

select * from (select rownum n, t.* from table t) where n between 2 and 10 

这会慢下来很多。这是为什么?

回答

10

为什么你认为这会减慢速度? Oracle不一定实例化子查询。

有两个原因需要用子查询编写。首先,您不能使用from子句中的select子句中定义的变量。要做到这一点,你需要子查询。第二个是你不能说where rownum between 2 and 10。当从select返回数据时,设置值为rownum。如果没有第一行返回,则第二行不会出现。

如果你关心性能,你可以这样做:

select * 
from (select rownum n, t.* 
     from table t 
     where rownum <= 10 
    ) 
where n between 2 and 10 

编辑:

使用rownum没有order by返回行的任意一组,这可能从一个执行变化到下一个。它不会返回一个“随机”集合(这是很难做到的)。它可能似乎返回插入到表中的第一行,但不能保证。

我在这种形式下离开解决方案,因为问题是关于“没有返回行”而不是返回哪些行。但是,如果没有order by,则这与(0123)在rownum <= 9中相当(如Rob在评论中所述)。

+2

你有没有睡觉?我想我有机会在深夜回答一些SQL问题,但是NOOOOO。 ;) –

+6

另外:1)没有ORDER BY子句的rownum没有意义。 2)正确性第一,表现第二! – LoztInSpace

+0

取决于作者的意图。如果意图获取特定的行,没有ORDER BY就没有意义。但如果意图只是标记返回的行,那就不同了。所提出的问题没有具体说明意图。这个解决方案只是标记行,在这种情况下不需要子查询。将ORDER BY添加到内部查询中,意义发生变化,这会更有意义。 – Glenn

1

如果你只是希望2和10之间的号码您的记录,也没有必要到子查询:

SELECT rownum + 1 AS n, s.* 
    FROM vzwnet.site_inst s 
    WHERE rownum < 10