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)文章
MacOS 下安裝 MySQL8.0 登陸 MySQL的方法
這篇文章主要介紹了MacOS 下安裝 MySQL8.0 登陸 MySQL 的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05windows7下啟動(dòng)mysql服務(wù)出現(xiàn)服務(wù)名無(wú)效的原因及解決方法
這篇文章主要介紹了windows7下啟動(dòng)mysql服務(wù)出現(xiàn)服務(wù)名無(wú)效的原因及解決方法,需要的朋友可以參考下2014-06-06linux下mysql數(shù)據(jù)庫(kù)單向同步配置方法分享
mysql數(shù)據(jù)庫(kù)單向同步又叫做主從復(fù)制,是通過(guò)二進(jìn)制日志文件完成的,注意:mysql 數(shù)據(jù)庫(kù)的版本,兩個(gè)數(shù)據(jù)庫(kù)版本要相同2012-06-06mysql的虛擬表(DUAL)的介紹及使用場(chǎng)景
本文主要介紹了mysql的虛擬表(DUAL)的介紹及使用場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-04-04MySQL創(chuàng)建用戶和權(quán)限管理的方法
這篇文章主要介紹了MySQL創(chuàng)建用戶和權(quán)限管理的方法,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07