select id,name from user where rownum <=1000
minus
select id,name from user where rownum <100
order by id不能用select *

解决方案 »

  1.   

    order by对rownum的结果没有影响的。
    select id,name from user where rownum <=1000
    minus
    select id,name from user where rownum <100
    ----------------------
    还可以使用rowid和rownum结合使用
      

  2.   

    select * from (select rownum rm,a.* from user a order by <排序>) where rm>100 and rm<=1000;
      

  3.   

    select *应该没有问题。
    用rownum是不行的,我原来写的sql就是象楼上一样的,虽然有order by排序了,但是rownum是不跟着排序走的(从测试结果来看,我觉得rownum是物理数据的编号,而非得到的记录集的编号) ,实际效果相当于select rownum rm,t.* from from table1 t where rm>100 and rm<=1000 order by <排序>,只不过是将指定rownum范围内的数据按照顺序排序了而已(已经测试得到验证)。问题我是需要在排序后的结果集上限制范围,不是一回事。
    我觉得通过rownum应该是行不通的,还望各位多多指点啊!!
    另:上面的一位说rowid,可否说的详细点?是用户字段还是系统字段?
      

  4.   

    另:用minus做集合减法不是效率会很低吗?还是在这里有什么特殊用途?
      

  5.   

    select * from table1 where <条件> order by <排序>
    where rowid>100 and rowid<1000
      

  6.   

    SQL> select max(rowid),min(rowid) from zd;MAX(ROWID)         MIN(ROWID)
    ------------------ ------------------
    AAAGfAAAKAAAA6aAAU AAAGfAAAKAAAA6aAAArowid不是数值型的,不能用>100这样的查询条件……
      

  7.   

    试试RANK()吧
    SELECT table_name from
    (select rank() over (order by table_name desc) rank1,table_name from user_tables
    order by table_name desc) ss
    where ss.rank1<=15 and ss.rank1<=100 order by table_name
    可以指定列来排序, 注意指定要在两个地方哦。
      

  8.   

    我在sqlplus里面试了一下,楼上的sql不行(我是认为table_name是列名,user_tables是表名来试的)。我的oracle是8.17的,我查了一下oracle8的PL/SQL的书,没有找到rank,能告诉我是因为版本问题还是什么?具体能在哪儿看到相关资料?
      

  9.   

    sql不好实现
    可以程序中
    i=10;
    while(i<=100)
    {
    i+=1;
    sql=select * from table order by xx;
    while(rs.next())
    {}
    }
      

  10.   

    楼上的程序有点费解…………我现在是用absolute(row_num)跳转的,应该比循环效率高一些,当然这个不是问题所在。我希望能得到SQL方式的支持。主要考虑是如果能直接用sql得到指定范围数据对于数据库压力应该小一些,我原先在sqlserver下有过这样的经验,如果不限制记录集大小速度上会有不小的差别,虽然oracle能力强,不过最好也能限制一下啊。
    另:sqlserver里有top子句指定检索范围,可惜oracle没有。
      

  11.   

    在oracle中怎么实现从一个排好序的结果集中查出指定的第n行到第n+m行数据,可以通过ROWNUM进行处理:先查询一个表的ROWNUM,然后根据该ROWNUM用BETWEEN..AND进行处理。如下(select x from (select x,rownum y from tablename) a where a.y between startnum and end order by x desc)
      

  12.   

    beckhambobo(beckham)的sql语句
    select * from (select rownum rm,a.* from user a order by <排序> )
     where rm>100 and rm<=1000;
    执行结果很对,关键是where,order by 在子查询里!
      

  13.   

    beckhambobo(beckham)的sql语句
    select * from (select rownum rm,a.* from user a order by <排序> )
    where rm>100 and rm<=1000;
    根据我的验证没有问题rownum不是物理编号,是结果集的编号,rowid才是记录的物理编号
    如下所示:
    1、顺序排序的结果
    SQL> select rownum,billing_type_id from billing_type where rownum<9 order by billing_type_id;    ROWNUM BILLING_TYPE_ID
    ---------- ---------------
             1               1
             2               2
             3               3
             4               4
             5               5
             6               6
             7               7
             8               8已选择8行。
    2、无排序的结果
    SQL> select rownum,billing_type_id from billing_type where rownum<9 ;    ROWNUM BILLING_TYPE_ID
    ---------- ---------------
             1               1
             2               2
             3               3
             4               4
             5               5
             6               8
             7               7
             8               9
    3、倒叙排序的结果
    SQL> select rownum,billing_type_id from billing_type where rownum<9 order by billing_type_id desc;    ROWNUM BILLING_TYPE_ID
    ---------- ---------------
             1               9
             2               8
             3               7
             4               6
             5               5
             6               4
             7               3
             8               2已选择8行。
    4、利用rownum进行取得无排序结果集中的一段数据
    SQL> select rw,billing_type_id from (select rownum rw,billing_type_id from billing_type) where rw>=3 and rw<=8;        RW BILLING_TYPE_ID
    ---------- ---------------
             3               3
             4               4
             5               5
             6               8
             7               7
             8               9已选择6行。5、利用rownum进行取得倒序排序结果集中的一段数据
    SQL> select rw,billing_type_id from (select rownum rw,billing_type_id from billing_type order by billing_type_id desc) where rw>=3 and rw<=8;        RW BILLING_TYPE_ID
    ---------- ---------------
             3               7
             4               6
             5               5
             6               4
             7               3
             8               2已选择6行。
    6、直接在简单查询语句中用rownum取一段数据
    SQL> select rownum,billing_type_id from billing_type where rownum>=3 and rownum<=9;未选定行
    7、取子查询结果集中一段数据,不排序并用rownum显示得出最终结果集
    SQL> select rownum,rw,billing_type_id from (select rownum rw,billing_type_id from billing_type) where rw>=3 and rw<=8;    ROWNUM         RW BILLING_TYPE_ID
    ---------- ---------- ---------------
             1          3               3
             2          4               4
             3          5               5
             4          6               8
             5          7               7
             6          8               9已选择6行。
    8、取子查询结果集中一段数据,排序并用rownum显示得出最终结果集
    SQL> select rownum,rw,billing_type_id from (select rownum rw,billing_type_id from billing_type) where rw>=3 and rw<=8 order by billing_type_id;    ROWNUM         RW BILLING_TYPE_ID
    ---------- ---------- ---------------
             1          3               3
             2          4               4
             3          5               5
             5          7               7
             4          6               8
             6          8               9已选择6行。仔细对照一、二两个测试中的rownum为6和8的两个结果以及测试三、四、五、六、七、八的结果,可以得出以下结论:
    1、rownum是结果集的逻辑编号
    2、有排序和rownum并存的简单语句是根据排序得出结果集,然后根据结果集的显示顺序得出rownum
    3、rownum在简单查询语句中,是个从1开始的逻辑编号,如果要使它成为能被利用的物理编号(不从1开始)必须放在子查询中
    4、对子查询的结果集进行排序和得出rownum的顺序和对表的简单查询语句之相应顺序完全不同(注意测试8中的rownum顺序,还真是比较奇怪!)是对子查询的结果集先得出rownum,再进行排序5、不是很清楚你问题的含义:是"取排序后的一段数据再显示"还是"取未排序的一段数据后再排序显示"
    前者:select * from (select rownum rm,a.* from user a order by <排序> )
    where rm>100 and rm<=1000
    后者:select * from (select rownum rm,a.* from user a)
    where rm>100 and rm<=1000 order by <排序>
      

  14.   

    还有测试九
    9、子查询中排序得出结果集,挑选其中的
    SQL> select rownum,rw,billing_type_id from (select rownum rw,billing_type_id from billing_type order by billing_type_id) where rw>=3 and rw<=8;    ROWNUM         RW BILLING_TYPE_ID
    ---------- ---------- ---------------
             1          3               3
             2          4               4
             3          5               5
             4          6               6
             5          7               7
             6          8               8已选择6行。
      

  15.   

    上面例子中表中初始数据:
    SQL> select billing_type_id from billing_type;BILLING_TYPE_ID
    ---------------
                  1
                  2
                  3
                  4
                  5
                  8
                  7
                  9
                  6已选择9行。
      

  16.   

    呵呵,其实我最早的程序的sql和beckhambobo(beckham)的sql语句是一样的,当时我是从同事那里问来的,自己并没有推敲过,偏偏他的sql里不涉及到排序的问题。
    我试了一下楼上的例子,我不知道是不是chenyanzhen(大法师)误会了我的意思,我测试了一下,并没有达到我的要求,不过,楼上的提醒了我rownum是记录集的编号,测试下来确实正确(不好意思,我因为太着急自己没有做很多测试)。
    其实我要实现的东西并不复杂,就好比论坛的1000个问题先按照某个时间顺序排列,然后在排列好的基础上再取出中间连续的多条,就好比取出排序后某一页应该显示的记录。不过我看了楼上的例子自己也试了一下,结果差别很大:
    我建了单字段的表testt2,内容如下:(为了直观我把顺序搞的不是很特殊化)
    SQL> select rownum,f1 from testt2;
        ROWNUM         F1
    ---------- ----------
             1          5
             2          2
             3          4
             4          3
             5          6
             6          1这是带排序的查询:
    SQL> select rownum,f1 from testt2 order by f1 desc;
        ROWNUM         F1
    ---------- ----------
             5          6
             1          5
             3          4
             4          3
             2          2
             6          1
    可以看出 rownum 确实是记录号,但是应该是排序前的记录号,在这个问题上与楼上的差异很大,楼上的从例3等例子里看出应该是排序后的记录号,我看了楼上的应该也是在sqlplus下运行的结果,因此我相信数据确实属实,数据库版本差异的可能性也不大,看来是设置问题了。
    先说一下我的环境是solaries 下的Oracle8.17,我回去试一下NT平台上的(单位的NT上的oracle我没有访问权限,没办法)。
    不过最让我欣慰的是,因为楼上的提示,我倒是想出来了在我目前环境的应该使用的sql。
    SQL> select rownum ,a.* from(select rownum rw,f1 from testt2 order by f1) a wher
    e rownum<5;    ROWNUM         RW         F1
    ---------- ---------- ----------
             1          6          1
             2          2          2
             3          4          3
             4          3          4
    现在就是排序后的rownum了,不过很不幸,where子句里不能写 rownum>[数值] ,否则都是空集,用between也一样。所以我又加了一层select试试:
    SQL> select* from(select rownum rw2,a.* from(select rownum rw1,f1 from testt2 or
    der by f1)a ) where rw2 between 2 and 5;       RW2        RW1         F1
    ---------- ---------- ----------
             2          2          2
             3          4          3
             4          3          4
             5          1          5
             
    %$%#^$^^%$#&^&!!!!!!!!!!!!!!!这次终于搞定了!(不过我希望有高人指点一下这里面存不存在效率问题)真的非常感谢各位参与,不管怎么说问题解决了。
    分我一定会散的,不好意思,只能散100,真的很想多散。不过我想等两天看看有没有人知道关于造成这个rownum如此大差异的原因在哪里,是否能够通过某种开关设置来搞定,毕竟我现在还是想用原来的sql,少一层select嵌套啊。
    希望各位继续踊跃参与,谢谢!!!
      

  17.   

    C:\>sqlplus scott/tiger@ora8dbSQL*Plus: Release 8.1.7.0.0 - Production on 星期四 4月 17 08:58:24 2003(c) Copyright 2000 Oracle Corporation.  All rights reserved.
    连接到:
    Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
    With the Partitioning option
    JServer Release 8.1.7.0.0 - ProductionSQL> select * from v$version ;BANNER
    ----------------------------------------------------------------
    Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
    PL/SQL Release 8.1.7.0.0 - Production
    CORE    8.1.7.0.0       Production
    TNS for 32-bit Windows: Version 8.1.7.0.0 - Production
    NLSRTL Version 3.4.1.0.0 - ProductionSQL> ed
    已写入文件 afiedt.buf  1  SELECT rank1, table_name from
      2  (select rank() over (order by table_name desc) rank1,table_name from user_tables
      3  order by table_name desc) ss
      4* where ss.rank1<=15 and ss.rank1>=10 order by table_name
    SQL> /     RANK1 TABLE_NAME
    ---------- ------------------------------
            15 REPCAT$_RESOLUTION
            14 REPCAT$_RESOLUTION_METHOD
            13 REPCAT$_RESOLUTION_STATISTICS
            12 REPCAT$_RESOL_STATS_CONTROL
            11 REPCAT$_RUNTIME_PARMS
            10 REPCAT$_SNAPGROUP已选择6行。
    很不好意思, 写了好久没有来看。
    其实它是可以的。
    你写的这么多的方法,我也要好好参考参考,有空我来好好读读。
      

  18.   

    结案陈词(呵呵):
    1、不好意思,不是版本的问题,版本跟你一样;问题出在我那个排序字段是主键,如果排序字段不是主键,是先出rownum,再排序;如果排序字段是主键,则先排序后出rownum,从而也解决了我上面自己的疑惑(上次测试时我已猜测到,只是急着出差没有测试)
    2、我说过rownum其实是oracle自己对结果集的标识,所以是从1开始的,如果要显示不是从1开始顺序显示的,必须先得出结果集,再过滤(就是采用子查询来实现)得到所要的结果,效率肯定是有影响的
    3、rank()也是一个好的解决办法,谢谢pumawang(还是叫小林吧..) 
    下面是关于rank的说明,抄了别人的东东
    The Oracle 8i analytic function RANK() allows you to rank each item in a group.Performing Top-N Queries in Oracle
    By Boris Milrud, Oracle Pro
     The task of retrieving the top or bottom N rows from a database table (by salary, sales amount, credit, etc.) is often referred to as a "top-N query." This task is fairly common in application development. 
    The most straightforward, but inefficient, way of accomplishing such a query is by retrieving all rows from the database table(s), sorting them by specified criteria, scanning from the top, and then selecting the top N rows. This is definitely not an elegant solution. Writing a procedure that retrieves and sorts all rows from a database table requires lots of code, and it probably won't execute as quickly as you'd expect. Use a single SQL statement to perform a top-N query. You can do so either by using the ROWNUM pseudocolumn available in several versions of Oracle or by utilizing new analytic functions available in Oracle 8i: RANK() and DENSE_RANK(). 
    RANK is an analytic function. It computes the rank of each row returned from a query with respect to the other rows returned by the query, based on the values of the value_exprs in the ORDER_BY_clause. Rows with equal values for the ranking criteria receive the same rank. Oracle then adds the number of tied rows to the tied rank to calculate the next rank. Therefore, the ranks may not be consecutive numbers. 
    DENSE_RANK is an analytic function. It computes the rank of each row returned from a query with respect to the other rows, based on the values of the value_exprs in the ORDER_BY_clause. Rows with equal values for the ranking criteria receive the same rank. The ranks are consecutive integers beginning with 1. The largest rank value is the number of unique values returned by the query. Rank values are not skipped in the event of ties.