在 MySQL 中,GROUP?BY用于將具有指定列中相同值的行分組在一起,允許對數(shù)據(jù)進行分類和聚合,即按照指定的字段或者表達式進行分組。
我們現(xiàn)在有一個簡單的表student,內(nèi)容如下表1所示:
對于上面這個表,我們要求查詢每個班幾個人?
答案是:select class,count(class) from student group by class;
有很多初學者在學習group by時,不明白為什么不是select * from student ?group by ?class,為什么一定不能是*,而是某一個列或者某個列的聚合函數(shù),group by 應(yīng)該怎么去理解呢?
上表如果執(zhí)行 select name from class;語句,應(yīng)該很好理解,展示如下表2內(nèi)容:
為了能夠更好的理解“group by”多個列“和”聚合函數(shù)“的應(yīng)用,我們在思考的過程中,由表1到表2的過程中,增加一個虛構(gòu)的中間表:虛擬表3。下面說說如何思考上面SQL語句執(zhí)行情況:
1.from ?student:該句執(zhí)行后,應(yīng)該結(jié)果和表1一樣,就是原來的student表。
2.from ?student ?group ?by ??class:該句執(zhí)行后,生成過程是這樣的:group ?by ?class,那么找class那一列,具有相同class值的行,合并成一行,我們想象生成了虛擬表3,如下所圖所示。如對于class值為”一班” 的,那么id為1,3,4的三行合并成1行,即所有的id值,name值和class值寫到一行里面,同樣,對于class值為”二班”的,那么id為2,3的二行合并成一行,所有的id值,name值和class值寫到一行里面。
3.接下來就要針對虛擬表3執(zhí)行Select語句了:
(1)如果執(zhí)行select *的話,那么返回的結(jié)果應(yīng)該是虛擬表3,可是id和name中有的單元格里面的內(nèi)容是多個值,而關(guān)系數(shù)據(jù)庫就是基于關(guān)系的,一個單元格中是不允許有多個值的,所以執(zhí)行select * 語句就報錯了。
(2)我們再看class列,每個單元格只有一個數(shù)據(jù),所以我們select class的話,就沒有問題了。為什么class列每個單元格只有一個值呢?因為我們就是用class列來group by的。
(3)那么對于id和name里面的單元格有多個數(shù)據(jù)的情況怎么辦呢?答案就是使用聚合函數(shù),聚合函數(shù)就用來輸入多個數(shù)據(jù),輸出一個數(shù)據(jù)的。如count(class)等聚合函數(shù),而每個聚合函數(shù)的輸入就是每一個多數(shù)據(jù)的單元格。
4、所以,我們執(zhí)行select ?class, count(class) ?from ?student ?group ?by ?class;,那么count(class)就對虛擬表3的class列的每個單元格進行count操作,最后執(zhí)行結(jié)果如下:
所以,通過上面的分析,如果對多個字段進行分組,原理也是一樣的。
Copyright ? 2013-2021 河南云和數(shù)據(jù)信息技術(shù)有限公司 豫ICP備14003305號 ISP經(jīng)營許可證:豫B-20160281