Sql ROWNUM如何在分页查询中工作?

Sql ROWNUM如何在分页查询中工作?,sql,oracle,pagination,rownum,Sql,Oracle,Pagination,Rownum,因此,我想在Oracle数据库中选择一系列行。我需要这样做,因为我的表中有数百万行,我想给用户分页结果如果你知道在客户端做这件事的另一种方法,我会使用JavaFX,如果这很重要,但我不认为通过网络发送所有数据在客户端分页是一个好主意 因此,读完这篇文章后,我有以下疑问: Select * From (Select t.*, rownum r from PERSON t) Where r > 100 and r < 110; 100和110只是一个例子。在应用程序中,我只需要求下限,

因此,我想在Oracle数据库中选择一系列行。我需要这样做,因为我的表中有数百万行,我想给用户分页结果如果你知道在客户端做这件事的另一种方法,我会使用JavaFX,如果这很重要,但我不认为通过网络发送所有数据在客户端分页是一个好主意

因此,读完这篇文章后,我有以下疑问:

Select * From (Select t.*, rownum r from PERSON t) Where r > 100 and r < 110;
100和110只是一个例子。在应用程序中,我只需要求下限,并添加一个大小为10_000的值来获取接下来的10_000行

现在rownum列出现在结果中,我不想看到它。由于我对SQL不是很有经验,下面是我的问题:

为什么这是我第一次尝试,直到我在上搜索,所以从rownum>100和rownum<110的人中选择*;返回0行

为什么没有简单的方法来做像选择。。。从…起rownum在下界和上界之间的位置

如何去掉结果值中的r列?显然,我需要从那里创建一个视图或一个临时表,但有没有其他方法考虑我的查询

它是否确保正确的分页?我阅读了ROWNUM分页一节,它说我应该按唯一的方式对值排序,以获得一致的分页,所以如果您可以确认的话,我想按ROWNUM排序是可以的。这不是违背了使用FIRST_ROWSN的目的吗


我希望不会太多,我可以分成几个单独的问题,但我认为将它们折叠起来是相关的,因为它们是密切相关的。

问题2的答案:在Oracle 12中,可以使用分页

select owner, object_name, object_id
from t
order by owner, object_name
OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY;

您有4个问题,全部围绕ROWNUM的用法和功能展开。我会逐一回答每个问题

为什么这是我第一次尝试,直到我在上搜索,所以从rownum>100和rownum<110的人中选择*;返回0行

Thomas Kyte关于ROWNUM和分页的出色解释

ROWNUM值在通过查询的谓词阶段之后,但在查询执行任何排序或聚合之前分配给行。此外,ROWNUM值只有在赋值后才会递增,这就是为什么以下查询永远不会返回行的原因:

select * 
  from t 
 where ROWNUM > 1;
因为ROWNUM>1对于第一行不是真的,所以ROWNUM不会前进到2。因此,没有任何ROWNUM值大于1

为什么没有简单的方法来做像选择。。。从…起rownum在下界和上界之间的位置

是的,有。从Oracle 12c开始,您可以使用新的Top-n行限制功能

例如,下面的查询将按升序返回第四高到第七高工资之间的员工:

SQL> SELECT empno, sal
  2  FROM   emp
  3  ORDER BY sal
  4  OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;

     EMPNO        SAL
---------- ----------
      7654       1250
      7934       1300
      7844       1500
      7499       1600

SQL>
如何去掉结果值中的r列

在外部查询中列出所需的列名,而不是选择*。对于频繁使用查询,创建视图是一项简单的一次性活动

或者,在SQL*Plus中,可以使用NOPRINT命令。它不会显示您不想显示的列名。但是,它只能在SQL*Plus中工作

比如说,

COLUMN column_name NOPRINT
SQL> desc dept
 Name                                      Null?    Type
 ----------------------------------------- -------- ------------
 DEPTNO                                             NUMBER(2)
 DNAME                                              VARCHAR2(14)
 LOC                                                VARCHAR2(13)

SQL> COLUMN dname NOPRINT
SQL> COLUMN LOC NOPRINT
SQL> SELECT * FROM dept;

    DEPTNO
----------
        10
        20
        30
        40

SQL>
SELECT val
FROM   (SELECT val, rownum AS rnum
        FROM   (SELECT val
                FROM   t
                ORDER BY val)
        WHERE rownum <= 8)
WHERE  rnum >= 5;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

SQL>
比如说,

COLUMN column_name NOPRINT
SQL> desc dept
 Name                                      Null?    Type
 ----------------------------------------- -------- ------------
 DEPTNO                                             NUMBER(2)
 DNAME                                              VARCHAR2(14)
 LOC                                                VARCHAR2(13)

SQL> COLUMN dname NOPRINT
SQL> COLUMN LOC NOPRINT
SQL> SELECT * FROM dept;

    DEPTNO
----------
        10
        20
        30
        40

SQL>
SELECT val
FROM   (SELECT val, rownum AS rnum
        FROM   (SELECT val
                FROM   t
                ORDER BY val)
        WHERE rownum <= 8)
WHERE  rnum >= 5;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

SQL>
它是否确保正确的分页

是的,如果正确编写分页查询

比如说,

COLUMN column_name NOPRINT
SQL> desc dept
 Name                                      Null?    Type
 ----------------------------------------- -------- ------------
 DEPTNO                                             NUMBER(2)
 DNAME                                              VARCHAR2(14)
 LOC                                                VARCHAR2(13)

SQL> COLUMN dname NOPRINT
SQL> COLUMN LOC NOPRINT
SQL> SELECT * FROM dept;

    DEPTNO
----------
        10
        20
        30
        40

SQL>
SELECT val
FROM   (SELECT val, rownum AS rnum
        FROM   (SELECT val
                FROM   t
                ORDER BY val)
        WHERE rownum <= 8)
WHERE  rnum >= 5;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

SQL>
或者,如上所示,在12c上使用新的行限制功能


很少有好的例子。

我通常写这样的查询:

select * 
from 
(
    select a.*, rownum as rn  
    from table_name a
    where rownum <= 110
)
where rn > 100 

这是我得到的最好的答案之一,所以。。。我希望我能投票两次:-只是Oracle12的新功能不要求我按唯一属性排序,对吗?当您需要排序的输出时,总是需要按排序。没有订单,就不能保证订购。这个新特性的好处是,您不需要子查询来进行第一次排序,您可以按顺序进行排序,并在同一查询中选择一个范围。但如果没有顺序,它将返回与select*From tableName相同顺序的行?这是我在SQL Developer中运行两个查询时观察到的行为,但我不确定是否总是这样。如果没有order by,这将毫无意义。这只是随机的。记住,没有默认的顺序,除非你明确提到一个订单。从表中选择*将以随机方式为您提供行。行永远不会按顺序存储,因此检索时会随机获取它们。只有当您提到“订购方”时,订单才有保证。因此,如果没有order by,它只会得到随机的行