Oracle 中 ROWNUM 使用问题记录

ROWNUM 使用问题记录(2023-08-17)

  • Oracle 版本: 19.0.0.0.0 Enterprise
  • 现象:今天在项目遇到一个问题,测试人员反馈前一天能看到的数据今天看不到了

用表格举例,这是前一天看到的数据,有9、7、1 这几个数量信息

日期 ID 数量
XXX 1 9
XXX 2 7
XXX 3 1

今天测试反馈 9 没了,但是库里是有的

ID 数量
XXX 2 7
XXX 3 1
XXX 4 1
  • 排查问题:我跟踪代码把SQL拿出来到数据库执行,确实没查出来数值 9 的数据
sql 复制代码
# SQL 如下(昨天能显示的时候ROWNUM 为<=20)
SELECT dt_date,id,num FROM T 
	WHERE dt_date>=2301 and dt_date<=2307 AND ROWNUM <= 10
	ORDER BY num DESC
  • 比较奇怪的是 ROWNUM<= 20 的时候能查出来为9 的那一条数据(其实即使查出来 9 数据结果也不对,因为还有一条数值为 12 的)
    • 先是改回 ROWNUM <= 20 确实能看到数值为9 的那一条数据了,但是还有一个数值12的没有查出来,还是不对
    • 通过回忆MYSQL的写法结合查询结果现象推测Oracle SQL 执行顺序与MYSQL不一样
      • 在MYSQL中上述SQL执行结果是正常的会取出数值为9 、12 的数据,MySql 会先执行Order By 操作,然后执行 Limit 取值,并且 Limit 会在Where 条件后执行
      • 在Oracle中就不行了,这里使用到了ROWNUM,而 ROWNUM 是写在 Where 条件中的,SQL 执行过程与Mysql 就产生了差异,根据现象得知Oracle先得到结果,然后生成虚拟的ROWNUM,再然后执行WHERE条件,最后 Orader By 操作,这样就出现了与测试反馈的一样的结果,取值在前排序在后,所以取出来的值如果刚巧数据满足要求时就不容易看出来问题
  • 解决问题:通过包装一层SQL来处理这个问题,先排序,再取值
sql 复制代码
# 通过嵌套SQL查询解决
SELECT * FROM (
  SELECT dt_date,id,num FROM T 
	WHERE dt_date>=2301 and dt_date<=2307
 	ORDER BY num DESC
) A
WHERE ROWNUM<=10
  • 本次问题根因:
  1. 太久(十多年了)没有使用过Oracle 了特性啥的早忘光光了,不然应该不会犯这个错误
  2. SQL 是老师提供的,我也没想那么多,直接用了,估计老师也可能也没想到吧
相关推荐
南城花随雪。10 分钟前
Redis(非关系型数据库)详细介绍
数据库·redis·nosql
冰红茶兑滴水17 分钟前
MySQL 内置函数
数据库·mysql
鸿·蒙23 分钟前
【PTA】【数据库】【SQL命令】编程题2
数据库·sql·pta
J.P.August37 分钟前
Oracle RAC 环境下数据文件误建在本地目录的处理过程
数据库·oracle
对酒当歌丶人生几何42 分钟前
Mybatis控制台打印SQL执行信息(执行方法、执行SQL、执行时间)
java·数据库·sql·mybatis
LightOfNight2 小时前
Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)
服务器·数据库·redis·分布式·后端·缓存·中间件
代码中の快捷键2 小时前
MySQL数据库存储引擎的数据结构
数据结构·数据库·mysql
Adolf_19932 小时前
Django 路由层
数据库
好记忆不如烂笔头abc2 小时前
logminer挖掘日志归档查找问题
数据库·sql·mysql
java_heartLake10 小时前
PostgreSQL数据库参数调优实践
数据库·postgresql·调优