有这么一张表:

create table hytb(
id number(4,0) not null primary key,
padid nvarchar2(20) not null,
inputdate date not null,
dosid integer not null
)

可以这样给它充值:

insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-23','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-26','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-23','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-27','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-28','yyyy-MM-dd'),'');

充完值是这样的结果集:

现在需要从中找出inputdate最近的三条记录(从图中目测是28-JAN-20,27-JAN-20,26-JAN-20),请问该怎么做?

首先可以利用row_number()函数:

select * from (select row_number() over (order by inputdate desc) as rn,hytb.* from hytb) a  where a.rn<4

其次可以利用rownum伪列:

select * from (select rownum as rn,a.* from (select * from hytb order by inputdate desc) a) b where b.rn<4

这两种SQL都是正确的,可以互相验证。

但是,下面的sql却是错误的:

select * from (select rownum as rn,hytb.* from hytb order by  inputdate desc) a where a.rn<4

执行结果如下:

为什么会出现这样的结果呢,让我们先看看其中子句select rownum as rn,hytb.* from hytb order by  inputdate desc的执行结果:

可以发现,伪列和id是一样的,并没有按时间排。

究其原因,是因为select子句的执行顺序在order by之前,在sql:

select rownum as rn,hytb.* from hytb order by  inputdate desc

里,首先执行的是

select rownum as rn,hytb.* from hytb

其次才是

order by  inputdate desc

也就是说,伪列先于order by执行,或者说 select子句先于order by子句执行,由于rownum在select子句中,所以rownum伪列先于order by执行。

关于SQL子句的执行顺序,可以参考:https://database.51cto.com/art/202001/609727.htm

这就是问题所在。

突破藩篱的感觉真好。

--2020-03-10--

以下是上面实验用到的所有sql,贴出来以供参考:

create table hytb(
id number(4,0) not null primary key,
padid nvarchar2(20) not null,
inputdate date not null,
dosid integer not null
) insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-23','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-26','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-23','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-27','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-24','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-25','yyyy-MM-dd'),'');
insert into hytb(id,padid,inputdate,dosid) values('','',to_date('2020-01-28','yyyy-MM-dd'),''); commit; truncate table hytb select * from hytb --Correct
select * from (select rownum as rn,a.* from (select * from hytb order by inputdate desc) a) b where b.rn<4 select * from (select row_number() over (order by inputdate desc) as rn,hytb.* from hytb) a where a.rn<4 --Wrong
select * from (select rownum as rn,hytb.* from hytb order by inputdate desc) a where a.rn<4

Oracle中select子句取值先于order by子句执行而导致rownum伪列未按预期取值导致的问题的更多相关文章

  1. Oracle中ROWNUM伪列和ROWID伪列的用法与区别

    做过Oracle分页的人都知道由于Oracle中没有像MySql中limit函数以及SQLServer中的top关键字等,所以只能通过伪列的方式去满足分页功能,在此,不谈分页方法,只从根本上去介绍这两 ...

  2. 1. 安装Oracle,配置环境 2. 实现查询From子句 3. 实现查询where子句 4. 实现查询order by子句

    一.环境安装1. 登录:以管理员身份登录 sqlplus 登录名/密码 管理员身份登录:sqlplus system/1234562. 登录后,导入案例.下载scott.sql文件,执行下面一行的命令 ...

  3. Oracle 中select XX_id_seq.nextval from dual 什么意思呢?

    说明 今天看别人的代码 ,遇见了 一条sql    select ctg_fault_list_id_seq.nextval from dual  不懂意思,然后就研究了下 dual :是oracle ...

  4. 论MySQL中如何代替Oracle中select into new_table from old_table

    v_receipt         warehouse_receipt%ROWTYPE;-- 这里创建表类型,v_receipt复刻了warehouse_receipt的类型(相当于拥有了所有相同的字 ...

  5. oracle中 SELECT INTO 和INSERT INTO ... SELECT区别

    在Oracle中,将一张表的数据复制到另外一个对象中.通常会有这两种方法:insert into select  和 select into from. 前者可以将select 出来的N行(0到任意数 ...

  6. Oracle中select使用别名

    1 .将字段用as转换成别名. 2 .直接在字段的名字后面跟别名. 3 .在字段后面用双引号引起的别名.   我的朋友 大鬼不动 最近访客 fhwlj kochiyas 大極星 Alz__ deser ...

  7. Oracle中select 1和select *的区别

    转自:https://www.linuxidc.com/Linux/2010-05/26202.htm 创建myt表并插入数据,如下: create table myt(name varchar2,c ...

  8. Oracle中Select语句完整的执行顺序

    oracle Select语句完整的执行顺序: .from 子句组装来自不同数据源的数据: .where 子句基于指定的条件对记录行进行筛选: .group by子句将数据划分为多个分组: .使用聚集 ...

  9. Hive中SELECT TOP N的方法(order by与sort by的区别)

    我想说的SELECT TOP N是取最大前N条或者最小前N条. Hive提供了limit关键字,再配合order by可以很容易地实现SELECT TOP N. 但是在Hive中order by只能使 ...

随机推荐

  1. SpringBoot整合Spring Security

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 Spring Securi ...

  2. Docker服务开放了这个端口,服务器分分钟变肉机

    之前有很多朋友提过,当使用docker-maven-plugin打包SpringBoot应用的Docker镜像时,服务器需要开放2375端口.由于开放了端口没有做任何安全保护,会引起安全漏洞,被人入侵 ...

  3. PythonCrashCourse 第四章习题

    Python 从入门到实践第四章习题 4.1想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for 循环将每种比萨的名称都打印出来 修改这个for 循环,使其打印包含比萨名称的句子,而不仅仅 ...

  4. C++统计单词数

    [题目描述] 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在 ...

  5. MySQL SQL概述

    MySQL SQL概述 数据库的好处: •实现数据持久化 •使用完整的管理系统统一管理易 数据库的概念: DB:数据库(database):存储数据的“仓库”.它保存了一系列有组织的数据. DBMS: ...

  6. HDFS的数据流读写数据 (面试开发重点)

    1 HDFS写数据流程 1.1 剖析文件写入 HDFS写数据流程,如图所示 1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是 ...

  7. 随机陷阱和P值

    如果让大家写一个50次的抛硬币实验的可能结果(头像H或字T),多半人在连续三个一样的后,会换一下.因为大家都知道,连续一样的越多,概率越小,越不可能发生.大部分人不会去想,其实HHHTT和HHHHH发 ...

  8. 结构体深度比较 reflect.DeepEqual

    demo1 package main import ( "fmt" "reflect" ) func main() { sliceMap1 := make([] ...

  9. Python之运维

    这几日一直研究运维监控的事情,有次看见有一个脚本写的还不错,如今已经找不到地址了 就只能用Python代替shell了 其中原理是 监控 /proc/下的各种文件,/proc/ 顾名思义其为进程的文件 ...

  10. [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).

    Linux下安装MySQL执行scripts/mysql_install_db --user=mysql脚本时,报错如下: Filling help tables...2019-12-24 16:46 ...