MySQL 对window函数执行sum函数疑似Bug
MySQL 对window函数执行sum函数疑似Bug
使用MySql的窗口函数统计数据时,发现一个小的问题,与大家一起探讨下。
环境配置:
- mysql-installer-community-8.0.20.0
问题点:在sum对window函数执行时,如果有重复数据,会直接把相同的数据相加,并不是逐步相加。
问题描述
数据:在一个成绩表中,有三个个字段:学生s_id,课程c_id,成绩s_score。
查询条件查询每个课程的学生成绩排名和成绩汇总。
查询结果:发现如果同一个课程有相同成绩是,汇总成绩不是累加的,而是一次全部加上去。
创建数据表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
)
插入数据
-- 成绩表数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
查询数据
select c_id,s_id,s_score,
first_value(s_score) over w as first_v,
last_value(s_score) over w as last_v,
sum(s_score) over w as sum_v,
max(s_score) over w as max_v,
min(s_score) over w as min_v,
count(s_id) over w as count_v,
row_number() over w as row_id,
rank() over w as rank_id,
dense_rank() over w as dense_id
from score window w as (partition by c_id order by s_score desc);
查询结果
看课程号01的统计结果,数据第一行的sum_v列,前两个数据都是160,按照函数原理,数据应该是80,160。
看课程号02的统计结果,发现结果是正确的,sum_v的第一个为90,第二个为179。
实际显示与预期结果不一致,哪里出了问题。
| c_id | s_id | s_score | first_v | last_v | sum_v | max_v | min_v | count_v | row_id | rank_id | dense_id |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 01 | 01 | 80 | 80 | 80 | 160 | 80 | 80 | 2 | 1 | 1 | 1 |
| 01 | 03 | 80 | 80 | 80 | 160 | 80 | 80 | 2 | 2 | 1 | 1 |
| 01 | 05 | 76 | 80 | 76 | 236 | 80 | 76 | 3 | 3 | 3 | 2 |
| 01 | 02 | 70 | 80 | 70 | 306 | 80 | 70 | 4 | 4 | 4 | 3 |
| 01 | 04 | 50 | 80 | 50 | 356 | 80 | 50 | 5 | 5 | 5 | 4 |
| 01 | 06 | 31 | 80 | 31 | 387 | 80 | 31 | 6 | 6 | 6 | 5 |
| 02 | 01 | 90 | 90 | 90 | 90 | 90 | 90 | 1 | 1 | 1 | 1 |
| 02 | 07 | 89 | 90 | 89 | 179 | 90 | 89 | 2 | 2 | 2 | 2 |
| 02 | 05 | 87 | 90 | 87 | 266 | 90 | 87 | 3 | 3 | 3 | 3 |
| 02 | 03 | 80 | 90 | 80 | 346 | 90 | 80 | 4 | 4 | 4 | 4 |
| 02 | 02 | 60 | 90 | 60 | 406 | 90 | 60 | 5 | 5 | 5 | 5 |
| 02 | 04 | 30 | 90 | 30 | 436 | 90 | 30 | 6 | 6 | 6 | 6 |
| 03 | 01 | 99 | 99 | 99 | 99 | 99 | 99 | 1 | 1 | 1 | 1 |
| 03 | 07 | 98 | 99 | 98 | 197 | 99 | 98 | 2 | 2 | 2 | 2 |
| 03 | 02 | 80 | 99 | 80 | 357 | 99 | 80 | 4 | 3 | 3 | 3 |
| 03 | 03 | 80 | 99 | 80 | 357 | 99 | 80 | 4 | 4 | 3 | 3 |
| 03 | 06 | 34 | 99 | 34 | 391 | 99 | 34 | 5 | 5 | 5 | 4 |
| 03 | 04 | 20 | 99 | 20 | 411 | 99 | 20 | 6 | 6 | 6 | 5 |
思考验证
课程号02的数据正确,01的不正确,01与02的区别是01课程的前两个学生成绩一样都是80。
难道是成绩一样,导致sum时出错了。
为了验证这个问题,把课程号01,学号为01的成绩修改为82,然后在执行查询,结果如下
发现sum_v列显示的为82、162,与预期结果一致。
这样可以得出结论,在sum对window函数执行时,如果有重复数据,会直接把相同的数据相加,并不是逐步相加。
| c_id | s_id | s_score | first_v | last_v | sum_v | max_v | min_v | count_v | row_id | rank_id | dense_id |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 01 | 01 | 80 | 80 | 82 | 82 | 82 | 82 | 2 | 1 | 1 | 1 |
| 01 | 03 | 80 | 80 | 80 | 162 | 82 | 80 | 2 | 2 | 1 | 1 |
| 01 | 05 | 76 | 80 | 76 | 236 | 82 | 76 | 3 | 3 | 3 | 2 |
| 01 | 02 | 70 | 80 | 70 | 306 | 82 | 70 | 4 | 4 | 4 | 3 |
| 01 | 04 | 50 | 80 | 50 | 356 | 82 | 50 | 5 | 5 | 5 | 4 |
| 01 | 06 | 31 | 80 | 31 | 387 | 82 | 31 | 6 | 6 | 6 | 5 |
| 02 | 01 | 90 | 90 | 90 | 90 | 90 | 90 | 1 | 1 | 1 | 1 |
| 02 | 07 | 89 | 90 | 89 | 179 | 90 | 89 | 2 | 2 | 2 | 2 |
| 02 | 05 | 87 | 90 | 87 | 266 | 90 | 87 | 3 | 3 | 3 | 3 |
| 02 | 03 | 80 | 90 | 80 | 346 | 90 | 80 | 4 | 4 | 4 | 4 |
| 02 | 02 | 60 | 90 | 60 | 406 | 90 | 60 | 5 | 5 | 5 | 5 |
| 02 | 04 | 30 | 90 | 30 | 436 | 90 | 30 | 6 | 6 | 6 | 6 |
| 03 | 01 | 99 | 99 | 99 | 99 | 99 | 99 | 1 | 1 | 1 | 1 |
| 03 | 07 | 98 | 99 | 98 | 197 | 99 | 98 | 2 | 2 | 2 | 2 |
| 03 | 02 | 80 | 99 | 80 | 357 | 99 | 80 | 4 | 3 | 3 | 3 |
| 03 | 03 | 80 | 99 | 80 | 357 | 99 | 80 | 4 | 4 | 3 | 3 |
| 03 | 06 | 34 | 99 | 34 | 391 | 99 | 34 | 5 | 5 | 5 | 4 |
| 03 | 04 | 20 | 99 | 20 | 411 | 99 | 20 | 6 | 6 | 6 | 5 |
其他Sql验证和对比
经过上述验证,Mysql在sum时确实出现了错误,不是逐步累加的。
其他平台是否同样存在问题,在Sqlite Expert 5.3版本验证了下,发现结果一样。
这个就奇怪了,如果是Mysql在实现时出错,Sqlite出同样错误的几率小很多。
难道是sum和window函数结合使用时的特性导致的。欢迎一起讨论和研究。
MySQL 对window函数执行sum函数疑似Bug的更多相关文章
- Mysql与Sql server,Sum函数跟Count函数
两者均是统计类函数,都不计算NULL字段!!! 单纯计算行数的话,count的效率比sum的效率高 MySQL SUM()函数介绍 SUM()函数用于计算一组值或表达式的总和,SUM()函数的语法如下 ...
- python 中的tile函数,shape函数,sum函数
1.tile函数: tile函数是模板numpy.lib.shape_base中的函数.函数的形式是tile(A,reps) A的类型几乎所有类型都可以:array, list, tuple, dic ...
- db2的count()函数和sum()函数的用法
一.count()函数可以使用参数,例如count(*)和count(列名) count(*)用来计算在指定条件下,满足条件的行数,例如: select count(*) from tablename ...
- Hibernate在PostgreSQL上执行sum函数导致数据失真的问题
有一段通过Hibernate从PostgreSQL上进行sum统计的简单代码,但统计结果却导致数据失真,不知原因何在,求指教! Java代码片段如下: public List<Object> ...
- 实际例子描述和分析“猎豹抢票跨站推荐功能有票刷不到”的疑似bug
前言 快过年了,又到了一年抢票时.今年douba和douma计划要带着doudou回姥姥家.昨天在家用抢票软件居然发现了一个bug,那就是在猎豹抢票中跨站推荐的车票几天里一直是没有,但是在12306手 ...
- DotNetBar滚动条的疑似BUG
1.重现过程,在winform窗体上拖一个VScrollBarAdv 2.Button里点击跟踪代码 3.Value居然是-5,,而不是0,这是直接赋值,不是手动拖的呀. 4.解决办法,将LargeC ...
- 发现一个企业微信第三方应用开发的疑似BUG
1.企业微信两个账号A(超级管理员),账号B(分级管理员),账号B具有创建应用与小程序权限.2.账号B添加一个第三方应用后(创建后能看到第三方应用),使用下图接口登录时回调的agent一直为空,3.超 ...
- 引用类型--Function类型(函数声明与函数表达式、arguments.callee、caller、apply、call、bind)
在ECMAScript中函数实际上是对象.每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定 ...
- 如果你也会C#,那不妨了解下F#(4):了解函数及常用函数
函数式编程其实就是按照数学上的函数运算思想来实现计算机上的运算.虽然我们不需要深入了解数学函数的知识,但应该清楚函数式编程的基础是来自于数学. 例如数学函数\(f(x) = x^2+x\),并没有指定 ...
随机推荐
- 离职冷静期文件.doc
<中华人民共和国民法典>通过十三届全国人大三次会议表决,将于2021年1月1日起施行,其中#离婚冷静期#备受关注.多方人士表示,离婚冷静期设立的出发点,不是对婚姻自由的一种破坏,而是让当事 ...
- HBase中加盐(Salting)之后的表如何读取:协处理器文章
我们介绍了避免数据斑点的三种比较常见方法: 加盐-盐腌 哈希-散列 反转-反转 其中在加盐(Salting)的方法里面是这么描述的:给Rowkey分配一个随机指针以使其和之前排序不同.但是在Rowke ...
- python中turtle模块画正多边形
画正多边形主要是计算多边形每个角度对应的外角的度数,计算出来这个度数即可画图,相对来说非常简单 以正六边形为例 import turtle import time t = turtle.Pen() f ...
- springboot整合Mybatis(有xml)
pom.xml <!-- mybatis 支持 SpringBoot --> <dependency> <groupId>org.mybatis.spring.bo ...
- C#数据结构与算法系列(五):常见单链表笔试
1.求单链表中有效节点个数 public static int GetLength(HeroNode headNode) { int length = ; var cur = headNode.Nex ...
- Zookeeper客户端Apache Curator
本文不对Zookeeper进行介绍,主要介绍Curator怎么操作Zookeeper. Apache Curator是Apache ZooKeeper的Java / JVM客户端库,Apache Zo ...
- JAVA 经典算法 40 例
[程序 1] 题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析: 兔子的规律为数列 ...
- 搜索引擎ElasticSearch入门
前言 最近项目上需要用到搜索引擎,由于之前自己没有了解过,所以整理了一下搜索引擎的相关概念知识. 正文 想查数据就免不了搜索,搜索就离不开搜索引擎,百度.谷歌都是一个非常庞大复杂的搜索引擎,他们几乎索 ...
- Centos 7使用systemctl补全服务名称
使用jsw将程序打包成服务后,发现不能使用service + 服务名前几个字母 + tab 快捷键补全服务名,但是tab键可以补全文件夹名,翻阅了各个文档后,最终还是找到了问题所在. 本人安装的是Ce ...
- Vue组件篇——Vue3.0中使用高德地图
VUE-CLI 3.0 中配置高德地图 在项目开发中,地图组件 1.首先,需要注册高德开放平台的账号,并在[应用管理]页面[创建新应用],为应用添加Key值 高德开放平台:https://lbs.am ...