zoukankan      html  css  js  c++  java
  • Oracle中rownum机制原理&用法详解

    1. 概述
    rownum是Oracle引入的虚列。
    在物理上这个虚列并不存在,只是在查询时才构造出来。伪列通常是自由分配的,用户无法执行修改等操作。

    2. 特点
    关于rownum有以下主要特点:

    1)rownum不属于任何表。
    2)rownum存在的前提,先有结果表。
    3)rownum总是从1开始。
    4)rownum一般只和<(<=)一起用。
    5)使用rownum进行分页查询需要把rownum转化为实列,并针对rownum查询。
    2. 机制原理
    rownum的用法看似奇怪,其实如果明白其机制原理就会很简单。
    首先我们来做个简单的实验:从dual表中取出所有的字段,并取出rownum。
    如果我们采用如下的写法:t.rownum

    这样运行就会报01747错:


    因为实际上,dual表就不存在rownum这个字段,所以我们无法使用t.rownum的格式。
    正确的写法,应该是:

    所以,rownum是一个虚列,不属于任何表。

    那么这虚列是怎么来的。我们在做个简单的实验,便于理解:
    如下,我们有一个简单的表:test_ljb,共有十条记录。
    我们加上rownum。

    结果如下,很好理解,选出十条记录,rownum从1到10


    我们加上一个salary的筛选条件:

    结果如下:选出三条记录,rownum从1到3


    需要注意的是,第二个结果表的rownum对应的employee和第一张并不对应。
    如:在第一张表rownum为1时,对应的时Arvin,而第二张对应的是Oracle。

    原因如下:
    因为rownum是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列。
    简单的说,rownum是对符合条件结果的序列号。它总是从1开始排起的,所以选出的结果不可能跳过1,而有其他大于1的值。
    或者说,rownum是一个动态的,根据新的结果集实时变化的。

    比如,如下语句:

    select t.*, rownum from test_ljb t where rownum >1; --大于2、3或者其他任何大于1的值,结果相同。

    我们发现没有符合条件的记录。

    根据原理,rownum是对结果集的从1开始排。那么以上的语句的结果集是什么呢?

    事实上,当执行完from test_ljb时,我们可以把他当作时一个结果表,rownum是从1-10。
    然后,重点,当我们执行过滤条件,rownum>1 时,第一条记录不满足,剔除。这个时候,新的结果集产生了,原来的第二条记录就成了第一条,相应的rownum变为了1-9。
    再次比较原来的第一条,现在的第二条记录,他的rownum也是1,也不满足,rownum是1-8。
    以此类推,流水的记录,铁打的rownum从1开始。所以,直到rownum是1,还不满足。所以最后没有记录被筛选出来,也没了rownum。

    所以,我们写出的这类语句:

    统统都是没结果的。

    不过有意思的是,选出前十条,可以有好多写法:

    3. 用法
    那有的同学就犯嘀咕了,我要做大于查询怎么搞啊,分页查询怎么搞啊,人家Mysql和Hive一个limit a, b 直接完事,你Oracle怎么搞。
    其实方法还是有的,也是用rownum,不过要先把这货转化为实列。加个子查询就可以了。
    老套路,简单实验走一波。

    3.1 大于查询
    还是test_ljb表,就选>5行。

    3.2.1 简单分页查询

    3.3.2 排序分页查询
    排序分页查询就麻烦了,首先要排序,然后再排序的基础上再筛选。
    当然这个也是实际项目最常用的。
    选出薪水最高的第4、5、6个。

    这里需要注意的是:rownum仅仅针对新的结果集动态标记,而排序并不会生成新的结果集,如果仅仅执行

    结果如下:

    注:这里写SQL语句时,注意缩进,有利于思路流畅。


    ---------------------
    作者:大数据JavaLiu_Arvin
    来源:CSDN
    原文:https://blog.csdn.net/qq_36743482/article/details/78919904
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    Delphi WinAPI SetLocaleInfo / GetLocaleInfo
    语言环境代码LCID对照表
    Delphi WinAPI SetThreadLocale
    光刻技术发展
    关于TVM的点滴记录
    TVM 各个模块总体架构
    TVM 图优化Graph Optimization
    Atomic Layer Deposition原子层沉积技术
    智加VS图森VS嬴彻
    汽车网络处理设计
  • 原文地址:https://www.cnblogs.com/elikun/p/10101288.html
Copyright © 2011-2022 走看看