前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从rownum的SQL需求还能归纳出的知识

从rownum的SQL需求还能归纳出的知识

作者头像
bisal
发布2019-03-11 13:55:25
5700
发布2019-03-11 13:55:25
举报

问题1

针对如下这条SQL,使用了row_number()函数,但外层使用了rownum,

640?wx_fmt=png
640?wx_fmt=png

老虎刘老师指出,

这种写法又回到最初了,相当于没用分析函数。 应该是分析函数生成的列给个别名,然后外层再用这个别名<=10,而不是还用rownum<=10。 使用分析函数和rownum,两个逻辑不一样的SQL得到相同结果集,只能说是巧合。

归根结底,缺少对这个函数的理解,还是需要重新领悟下ROW_NUMBER(),他的定义如下,

代码语言:javascript
复制
ROW_NUMBER() OVER ([query_partition_clause] order_by_clause)

ROW_NUMBER()为查询出来的每一行记录生成一个序号,依次排序且不会重复,能用于实现top-N、bottom-N、inner-N,

ROW_NUMBER is an analytic function. It assigns a unique number to each row to which it is applied (either each row in the partition or each row returned by the query), in the ordered sequence of rows specified in the order_by_clause, beginning with 1. This use of the function lets you implement top-N, bottom-N, and inner-N reporting

这是《Reference》的示例,可以看出department_id相同的记录,别名是emp_id,会标记序号,而且按照employee_id的顺序进行排列,体现出ROW_NUMBER()的作用,

640?wx_fmt=png
640?wx_fmt=png

这个则是实现inner-N,返回按照last_name排序的51-100条记录,

640?wx_fmt=png
640?wx_fmt=png

相应地,针对我们的需求,改为如下SQL,将ronwum<=10改为row_number()<=10,而且注意个细节,即使内层查询,没有order by name desc将bbb排在aaa前面,此时使用t.c='aaa' OR t.c='bbb' AND t.e <= 10作为条件,并不会像《从一条"错误"的SQL,了解rownum的作用》中使用NAME='aaa' OR NAME='bbb' AND ROWNUM<=10作为条件,得到19条aaa和1条bbb,而是返回正确的19条aaa和10条bbb,

640?wx_fmt=png
640?wx_fmt=png

问题2

有一位朋友说,

我想通过union all来实现,一个取符合要求的aaa,一个是取bbb,最后一合并,可以,虽然有点慢。但是这样是没有顺序的,但是,当我要order by rowid时候,就报了错(ORA 01446)。

他用的SQL如下,

640?wx_fmt=png
640?wx_fmt=png

ORA-01446的错误提示看,原因是无法从带distinct、group by的视图中检索ROWID,

01446, 00000, "cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc." // *Cause: // *Action:

我们从这条SQL,对应的执行计划,就能看出来,需要排序的是内层子查询视图的结果集,而视图的SELECT检索项中没有ROWID,所以根本不知道按照谁的ROWID进行排序,抛出错误ORA-01446,

640?wx_fmt=png
640?wx_fmt=png

因此,只需要在子查询中的SELECT,增加ROWID字段,外层就能按照ROWID,进行排序,

640?wx_fmt=png
640?wx_fmt=png

问题3

将问题1和问题2,进行结合,还能解决name按照rowid排序的问题,

640?wx_fmt=png
640?wx_fmt=png

对应执行计划,如下所示,

640?wx_fmt=png
640?wx_fmt=png

P.S.

对于数据检索的顺序,多说一句,有时你看见的,未必是真相,可以参考《Oracle读取数据的顺序问题》中对数据检索顺序的探索。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年02月20日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档