MySQL對(duì)window函數(shù)執(zhí)行sum函數(shù)可能出現(xiàn)的一個(gè)Bug
使用MySql的窗口函數(shù)統(tǒng)計(jì)數(shù)據(jù)時(shí),發(fā)現(xiàn)一個(gè)小的問(wèn)題,與大家一起探討下。
環(huán)境配置:
- mysql-installer-community-8.0.20.0
問(wèn)題點(diǎn):在sum對(duì)window函數(shù)執(zhí)行時(shí),如果有重復(fù)數(shù)據(jù),會(huì)直接把相同的數(shù)據(jù)相加,并不是逐步相加。
問(wèn)題描述
數(shù)據(jù):在一個(gè)成績(jī)表中,有三個(gè)個(gè)字段:學(xué)生s_id,課程c_id,成績(jī)s_score。
查詢條件查詢每個(gè)課程的學(xué)生成績(jī)排名和成績(jī)匯總。
查詢結(jié)果:發(fā)現(xiàn)如果同一個(gè)課程有相同成績(jī)是,匯總成績(jī)不是累加的,而是一次全部加上去。
創(chuàng)建數(shù)據(jù)表
CREATE TABLE `Score`( `s_id` VARCHAR(20), `c_id` VARCHAR(20), `s_score` INT(3), PRIMARY KEY(`s_id`,`c_id`) )
插入數(shù)據(jù)
-- 成績(jī)表數(shù)據(jù)
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);
查詢數(shù)據(jù)
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);
查詢結(jié)果
看課程號(hào)01的統(tǒng)計(jì)結(jié)果,數(shù)據(jù)第一行的sum_v列,前兩個(gè)數(shù)據(jù)都是160,按照函數(shù)原理,數(shù)據(jù)應(yīng)該是80,160。
看課程號(hào)02的統(tǒng)計(jì)結(jié)果,發(fā)現(xiàn)結(jié)果是正確的,sum_v的第一個(gè)為90,第二個(gè)為179。
實(shí)際顯示與預(yù)期結(jié)果不一致,哪里出了問(wèn)題。
| 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 |
思考驗(yàn)證
課程號(hào)02的數(shù)據(jù)正確,01的不正確,01與02的區(qū)別是01課程的前兩個(gè)學(xué)生成績(jī)一樣都是80。
難道是成績(jī)一樣,導(dǎo)致sum時(shí)出錯(cuò)了。
為了驗(yàn)證這個(gè)問(wèn)題,把課程號(hào)01,學(xué)號(hào)為01的成績(jī)修改為82,然后在執(zhí)行查詢,結(jié)果如下
發(fā)現(xiàn)sum_v列顯示的為82、162,與預(yù)期結(jié)果一致。
這樣可以得出結(jié)論,在sum對(duì)window函數(shù)執(zhí)行時(shí),如果有重復(fù)數(shù)據(jù),會(huì)直接把相同的數(shù)據(jù)相加,并不是逐步相加。
| 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驗(yàn)證和對(duì)比
經(jīng)過(guò)上述驗(yàn)證,Mysql在sum時(shí)確實(shí)出現(xiàn)了錯(cuò)誤,不是逐步累加的。
其他平臺(tái)是否同樣存在問(wèn)題,在Sqlite Expert 5.3版本驗(yàn)證了下,發(fā)現(xiàn)結(jié)果一樣。
這個(gè)就奇怪了,如果是Mysql在實(shí)現(xiàn)時(shí)出錯(cuò),Sqlite出同樣錯(cuò)誤的幾率小很多。
難道是sum和window函數(shù)結(jié)合使用時(shí)的特性導(dǎo)致的。歡迎一起討論和研究。
總結(jié)
到此這篇關(guān)于MySQL對(duì)window函數(shù)執(zhí)行sum函數(shù)可能出現(xiàn)的一個(gè)Bug的文章就介紹到這了,更多相關(guān)MySQL對(duì)window函數(shù)執(zhí)行sum函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Win10系統(tǒng)安裝MySQL8.0遇到的問(wèn)題
這篇文章主要介紹了Win10系統(tǒng)安裝MySQL8.0遇到的問(wèn)題及解決方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2019-12-12
MySQL索引的一些常見(jiàn)面試題大全(2022年)
索引(Index)是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),是對(duì)表中一列或多列值進(jìn)行排序的結(jié)構(gòu),下面這篇文章主要給大家介紹了關(guān)于MySQL索引的一些常見(jiàn)面試題,文中介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
MySQL8.0.30(zip版)windows安裝過(guò)程
這篇文章主要介紹了MySQL8.0.30(zip版)windows安裝,進(jìn)入到mysql下載頁(yè)面后選擇zip版本點(diǎn)擊下載,下載完以后把它解壓到自己想存放的位置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09
MySQL數(shù)據(jù)庫(kù)手冊(cè)DATABASE操作與編碼(小白入門(mén)篇)
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)手冊(cè)DATABASE操作與編碼的小白入門(mén)篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
mysql exists與not exists實(shí)例詳解
這篇文章主要介紹了mysql exists與not exists實(shí)例詳解的相關(guān)資料,鑒于 not exists 的效率往往要高于 not in , 所以一般情況下會(huì)使用前者替代后者,需要的朋友可以參考下2017-07-07
MySQL系列理解運(yùn)用union(all)與limit及exists關(guān)鍵字教程
這篇文章主要為大家介紹了MySQL系列中union(all)、limit及exists關(guān)鍵字的教程示例講解,通過(guò)本篇文章就可以理解MySQL中的這些關(guān)鍵字的概念以及實(shí)際的運(yùn)用2021-10-10

