MySQL 8.0 窗口函数框架用法-爱可生( 二 )
|1|1|1|
|1|2|3|
|1|3|5|
|1|9|12|
|1|10|19|
|1|15|25|
+------+------+-----------+
6rowsinset(0.00sec)
带表达式的边界只是把无边界换成具体的行号 。 上面的查询表达的意思是基于分组内每行记录和它上一条记录求和 , 不累加 。 可以看到wf_result的具体值 , 25对应的是10和15求和 , 19对应的是9和10求和 。
那以此类推 , 求每行和它上面两行的和:
mysql:ytt_80>selectid,r1,sum(r1)over(partitionbyidorderbyr1ascrows2preceding)aswf_resultfromt1whereid=1;
+------+------+-----------+
|id|r1|wf_result|
+------+------+-----------+
|1|1|1|
|1|2|3|
|1|3|6|
|1|9|14|
|1|10|22|
|1|15|34|
+------+------+-----------+
6rowsinset(0.00sec)
再来求每行的前两行和后面四行相加的结果:
mysql:ytt_80>selectid,r1,sum(r1)over(partitionbyidorderbyr1ascrowsbetween2precedingand4following)
aswf_resultfromt1whereid=1;
+------+------+-----------+
|id|r1|wf_result|
+------+------+-----------+
|1|1|25|
|1|2|40|
|1|3|40|
|1|9|39|
|1|10|37|
|1|15|34|
+------+------+-----------+
6rowsinset(0.00sec)
其实rows单元很简单 , 接下来看下range , range稍微难理解些 。
5、rangepreceding/following求当前行值范围内的分组记录 。 这个没有rows好理解 , rows对应的是行号 , range对应的行值 。 看下面例子:
mysql:ytt_80>selectid,r1,sum(r1)over(partitionbyidorderbyr1ascrange1preceding)aswf_resultfromt1whereid=1;
+------+------+-----------+
|id|r1|wf_result|
+------+------+-----------+
|1|1|1|
|1|2|3|
|1|3|5|
|1|9|9|
|1|10|19|
|1|15|15|
+------+------+-----------+
6rowsinset(0.00sec)
这个例子包含的关键词range1preceding , 是个表达式条件 , 表示对于分组内每一行来讲:以字段r1当前行值减去1的结果为边界来求和 。 具体点就是:第一行 , r1的值为1 , 那1-1=0 , 由于表t1里没有找到r1=0的结果 , 所以此时wf_result=1 , 也就是等于当前行值;对于第五行 , 由于r1对应的值为10,10-1=9,表t1里r1=9是存在的 , 此时求和结果为9+10=19 。
再次带上范围来看下另外一个例子:
mysql:ytt_80>selectid,r1,sum(r1)over(partitionbyidorderbyr1ascrangebetween1precedingand1following)aswf_resultfromt1whereid=1;
+------+------+-----------+
|id|r1|wf_result|
+------+------+-----------+
|1|1|3|
|1|2|6|
|1|3|5|
|1|9|19|
|1|10|19|
|1|15|15|
+------+------+-----------+
6rowsinset(0.00sec)
这个例子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.
这里举例说明了MySQL8.0窗口函数frame子句的用法 , 可能使用场景比较稀少 , 不过可以收藏起来以备不时之需 。
之前在MySQL8.0新特性栏目里介绍过8.0的窗口函数的用法 , 没有细化到全部的语法 , 恰巧今天有客户追问其中的框架子句用法 , 写出来大家一起探讨 。
窗口函数其实就是一个分组窗口内部处理每条记录的函数 , 这个窗口也就是之前聚合操作的窗口 。 不同的是 , 聚合函数是把窗口关闭 , 给一个汇总的结果;而窗口函数是把窗口打开 , 给分组内每行记录求取对应的聚合函数值或者其他表达式的结果 。
今天重点看窗口函数内的frame子句:frame子句用来把窗口内的记录按照指定的条件打印出来 , 跟在partition和orderby子句后面 。 frame子句的语法为:
frame_clause:
frame_unitsframe_extent
frame_units:
{ROWS|RANGE}
frame_extent:
{frame_start|frame_between}
frame_between:
BETWEENframe_startANDframe_end
frame_start,frame_end:{
CURRENTROW
|UNBOUNDEDPRECEDING
|UNBOUNDEDFOLLOWING
|exprPRECEDING
|exprFOLLOWING
}
这里分为两块 , 一块是frame_units(框架单元) , 另外一块是frame_extent(框架内容)
frame_units框架单元有两个 , 一个是rows , 一个是range 。
rows后面跟的内容为指定的行号 , 而range不同 , range是指的行内容 。
框架内容看起来挺多分类 , 其实就一句话来表达:为了定义分组内对应行记录的边界值来求取对应的计算结果 。
基于t1举例说明下:
mysql:ytt_80>desct1;
+-------+------+------+-----+---------+-------+
|Field|Type|Null|Key|Default|Extra|
+-------+------+------+-----+---------+-------+
|id|int|YES||NULL||
|r1|int|YES||NULL||
|r2|int|YES||NULL||
- 鹿晗主演网剧豆瓣评分8.0,《穿越火线》为什么依旧这么火?
- 等了三年终于有中文了?小窗口中的王道日式幻想RPG
- 微信状态怎么删
- 大市值白马股何时可抄底?私募:部分股票左侧交易窗口逐步开启
- 「牛人重仓」奇信股份:日内跌幅超过10%,今日资金流入-1948.04万元;前3个交易日,主力资金净流入2051.94万元
- 宝马小米智能电视盒 - 了解世界的窗口
- DockMate for Mac(应用窗口管理)
- MySQL数据库技术与应用(教学大纲)
- MySQL数据实时克隆的初步设计
- 女子银行存20万元现金,怒怼工作人员:一共9个窗口,6个不营业
