<p><blockquote>作者:杨涛涛<br/>资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。<br/>本文来源:原创投稿<br/>* 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。<br/></blockquote></p><p>之前在 MySQL 8.0 新特性栏目里介绍过 8.0 的窗口函数的用法,没有细化到全部的语法,恰巧今天有客户追问其中的框架子句用法,写出来大家一起探讨。</p><p>窗口函数其实就是一个分组窗口内部处理每条记录的函数,这个窗口也就是之前聚合操作的窗口。不同的是,聚合函数是把窗口关闭,给一个汇总的结果;而窗口函数是把窗口打开,给分组内每行记录求取对应的聚合函数值或者其他表达式的结果。</p><p>今天重点看窗口函数内的 frame 子句:frame 子句用来把窗口内的记录按照指定的条件打印出来,跟在 partition 和 order by 子句后面。frame 子句的语法为:</p><p></p><p>这里分为两块,一块是 frame_units (框架单元),另外一块是 frame_extent (框架内容)</p><p><ul><li></p><p>• frame_units 框架单元有两个,一个是 rows,一个是 range。</p><p></li><li></p><p>• rows 后面跟的内容为指定的行号,而 range 不同,range 是指的行内容。</p><p></li></ul></p><p>框架内容看起来挺多分类,其实就一句话来表达: 为了定义分组内对应行记录的边界值来求取对应的计算结果。</p><p>基于 举例说明下:</p><p></p><p>1、CURRENT ROW</p><p>表示获取当前行记录,也就是边界是当前行,等值关系</p><p></p><p>这里我们求 ID 为 1 的分组记录,基于聚合函数 SUM 来对分组内的行记录按照一定的条件求和。其中 OVER 子句用来定义分区以及相关条件,这里表示只获取分组内排序字段的当前行记录,也就是字段 r1 对应的记录,这是最简单的场景。</p><p>2、UNBOUNDED PRECEDING</p><p>表示边界永远为第一行</p><p></p><p>以上 unbounded preceding 用来获取表 t1 按照字段 ID 来分组,并且对字段 r1 求和。由于都是以第一行,也就是 r1 = 1 为基础求和,也就是求取上一行和当前行相加的结果,基于第一行记录。 这个例子中 r1 字段的第一行记录为 1,后面的所有求和都是基于第一行来累加的结果。</p><p>3、unbounded following</p><p>表示边界永远为最后一行</p><p></p><p>以上用了 rows between 把边界局限在第一行和最后一行,这样每行的求和结果和不带边界一样,也就是下面查询:</p><p></p><p>4、expr preceding / following</p><p>带表达式的边界,</p><p></p><p>带表达式的边界只是把无边界换成 具体的行号。 上面的查询表达的意思是基于分组内每行记录和它上一条记录求和,不累加。可以看到 wf_result 的具体值,25 对应的是 10 和 15 求和,19 对应的是 9 和 10 求和。</p><p>那以此类推,求每行和它上面两行的和:</p><p></p><p>再来求每行的前两行和后面四行相加的结果:</p><p></p><p>其实 rows 单元很简单,接下来看下 range ,range 稍微难理解些。</p><p>5、range preceding / following</p><p>求当前行值范围内的分组记录。 这个没有 rows 好理解,rows 对应的是行号,range 对应的行值。看下面例子:</p><p></p><p>这个例子包含的关键词 range 1 preceding ,是个表达式条件,表示对于分组内每一行来讲:以字段 r1 当前行值减去1的结果为边界来求和。具体点就是:第一行,r1 的值为 1,那 1-1=0, 由于表 t1 里没有找到 r1 = 0 的结果,所以此时 wf_result = 1,也就是等于当前行值;对于第五行,由于 r1 对应的值为 10 , 10 - 1 = 9 ,表 t1 里 r1 = 9 是存在的,此时求和结果为 9 + 10 = 19。</p><p>再次带上范围来看下另外一个例子:</p><p></p><p>这个例子 over 子句里指定一个边界范围,也就是对每行值减1和加1后对应的记录来求和。比如第一行:r1 = 1,1 -1 =0,1+1 =2,表 t1 没有 r1 = 0 的记录,但是有 r1 = 2 的记录,所以第一行的窗口求和结果为 3;再来看看 r1 = 10 的这行,10-1 = 9,10+1 = 11, 表 t1 里有 r1 = 9 的记录,没有 r1 = 11 的记录,所以这里的求和结果为 9+10=19.</p><p>这里举例说明了 MySQL 8.0 窗口函数 frame 子句的用法,可能使用场景比较稀少,不过可以收藏起来以备不时之需。</p>
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/169905.html