关于order by中的数据排序(r4笔记第6天)
今天开发的一个同事找到我,说碰到一个比较奇怪的问题,说两个等价的查询类似下面的形式。
select *from test where account_id=xxxxxx order by creation_date
select *from test where account_id=xxxxxx and entity_id=xxxxx order by creation_date
两个查询都会返回4条结果,但是第一个查询和第二个查询的结果排序结果不一致。
使用第一个查询的结果如下:
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
使用第2个查询的结果如下
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 1 130000000003403
09-AUG-14 170000501 2 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
order by的时候是根据第1个字段排序的,但是第3个字段的排序结果却不同。单纯从sql语句的角度来说,似乎也是合乎情理的。
当时首先想到的就是把creation_date格式化为更加精细的日期格式,精确到秒,看看时间,结果查看了最终的日期格式,发现精度都一样,印象中10g以后的order by算法做了变更。是不是这个原因导致的呢。
为了证明我的想法,自己做了一个简要的测试,反复的比较之后发现order by在指定字段排序后,其它字段的排序和以下的几种场景有关。
和rowid有一定的关系
和索引相关
和null值相关
为了证明,我在反复尝试之后,使用了下面的例子。
我们创建一个表test,然后插入一些针对性的数据。
create table test(creation_date date,ACCOUNT_ID number,INST_FROM number,TLG_INST_ID number, CHG_SEQ_NO number);
insert into test values(to_date('2014-09-11','yyyy-mm-dd'),170000501,4,130000000003403,'');
insert into test values(to_date('2014-08-09','yyyy-mm-dd'),170000501,2,130000000003403,'');
insert into test values(to_date('2014-08-09','yyyy-mm-dd'),170000501,1,130000000003403,16310);
insert into test values(to_date('2014-09-0','yyyy-mm-dd'),170000501,3,130000000003403,'');
这个时候查询结果,可以看到inst_from字段是按照4,2,1,3的顺序显示的。这个时候没有任何的排序操作。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403'
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
11-SEP-14 170000501 4 130000000003403
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
我们略做改动,使用order by creation_date,可以看到inst_from字段会按照2,1,3,4的顺序显示了。这个时候做了排序操作,但是相对前2条数据,因为插入inst_from的顺序是按照先2,1的顺序来的,所以排序后的结果就是先2,1的顺序。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
这个时候我们创建一个索引,注意我们使用了一个含有空值的列 chg_seq_no.
create index inx_test on test(TLG_INST_ID,CHG_SEQ_NO);
这个时候再次使用排序,结果集就有了明显的差别。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 1 130000000003403 16310
09-AUG-14 170000501 2 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
值得注意的是,如果我们创建的索引不含有空值列,
create index inx_test on test(TLG_INST_ID);
输出的排序结果和没有创建索引没有什么区别。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
通过上面的测试,也发现在order by的时候还是存在很多的不确定性,这些都可以通过在order by之后指定排序的列来避免。但是对理解order by来说,这些测试还是能够看到order by在实现方式上还是有很多的技巧的。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 如何修复WordPress死亡白屏(WSoD)故障问题
- linux: 添加一个IP地址
- Nginx简易防CC策略规则
- 如何编写和优化WordPress网站的Robots.txt
- 如何处理WordPress网站404状态死链
- (三)RecyclerView简单滑动场景分析
- AWS EC2实例开启IPv6方法 阅读模式
- centos7宝塔环境安装VeryNginx waf系统实现高级防火墙功能
- 腾讯云中关于授权子用户QCloudResourceFullAccess权限后使用api接口创建购买cvm没有支付权限的解决办法
- centos7中systemctl系统服务和资源限制故障
- centos7 安装zabbix并监控windows服务器
- 宝塔面板插件-shadowsocks可视化管理
- Android面试知识笔记:那些年面试官常问的知识点...(附详细解析)
- 聊聊dubbo-go的failbackCluster
- Docker环境准备