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

use*_*315 8 sql oracle pagination rownum

所以我想在Oracle DB中选择一系列行.我需要这样做,因为我在表中有数百万行,我想将结果分页给用户(如果你知道在客户端执行此操作的另一种方法,我使用JavaFX,如果它很重要,但我不认为通过网络发送所有数据以在客户端对它们进行分页是个好主意.

所以看完这篇文章后:SQL ROWNUM如何在特定范围之间返回行,我有以下查询:

Select * From (Select t.*, rownum r from PERSON t) Where r > 100 and r < 110;
Run Code Online (Sandbox Code Playgroud)

100110只是例子.在应用程序中,我只要求下限并添加10_000的大小以获取下一个10_000行.

现在rownum列出现在结果中,我不想看到它.由于我对SQL不是很熟悉,所以我的问题是:

  1. 为什么(这是我在SO上搜索的第一次尝试)Select * From Person Where rownum > 100 and rownum < 110;返回0行?
  2. 为什么没有简单的方法做某事Select ... FROM ... WHERE rownum BETWEEN lowerBound AND upperBound

  3. 如何摆脱r结果值中的列?从那里SQL使用SELECT*[除了columnA] FROM tableA排除一列?我显然需要创建一个视图或临时表,但考虑我的查询还有另一种方法吗?

  4. 它确保正确的分页吗?我读了这篇文章 "用ROWNUM分页",它说我应该通过一些独特的东西来命令这些值以获得一致的分页(所以rownum如果你能确认,我猜测排序很好).它不会破坏使用目的FIRST_ROWS(N)吗?

我希望它不是太多,我可以分成不同的问题,但我认为让它们紧密相关是有意义的.

谢谢 :)

Lal*_*r B 26

您有4个问题,所有问题都围绕着ROWNUM的使用和功能.我将逐一回答每个问题.

为什么(这是我第一次尝试直到我搜索SO)选择*来自人的地方rownum> 100和rownum <110; 返回0行?

由托马斯·凯特关于ROWNUM和分页尼斯解释这里.

ROWNUM它通过后值被分配给行谓词相的查询,但查询之前是否有任何分选或聚集.此外,ROWNUM值仅在分配后递增,这就是以下查询永远不会返回行的原因:

select * 
  from t 
 where ROWNUM > 1;
Run Code Online (Sandbox Code Playgroud)

因为第一行的ROWNUM> 1不成立,所以ROWNUM不会前进到2.因此,ROWNUM值不会大于1.

为什么没有简单的方法可以做一些像Select ... FROM ... WHERE rownum BETWEEN lowerBound和upperBound?

就在这里.从Oracle 12c开始,您可以使用新的Top-n Row限制功能.在这里看到我的答案.

例如,以下查询将按升序将员工退回到4高第7高薪之间:

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>
Run Code Online (Sandbox Code Playgroud)

如何摆脱结果值中的r列?

而不是select *在外部查询中列出所需的列名称.对于经常使用查询,创建视图是一个简单的一次性活动.

或者,SQL*Plus您可以使用NOPRINT命令.它不会显示您不想显示的列名称.但是,它只适用于SQL*Plus.

例如,

COLUMN column_name NOPRINT
Run Code Online (Sandbox Code Playgroud)

例如,

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>
Run Code Online (Sandbox Code Playgroud)

它确保正确的分页吗?

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

例如,

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>
Run Code Online (Sandbox Code Playgroud)

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

这里几个很好的例子.

  • 没有订单,它将毫无意义.这只是随机的.请记住,除非您明确提及订单,否则没有默认订单.`select*from table`将以随机方式为您提供行.行永远不会按顺序存储,因此当您检索时,它们是随机提取的.只有在您提到订单时才能保证订单.因此,没有订单只是获得随机行. (2认同)

Rob*_*ebe 6

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

select owner, object_name, object_id
from t
order by owner, object_name
OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)


Pav*_*rov 5

我通常会写这样的查询:

select * 
from 
(
    select a.*, rownum as rn  
    from table_name a
    where rownum <= 110
)
where rn > 100 
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

11624 次

最近记录:

10 年,5 月 前