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