1. 程式人生 > >MYSQL的高階查詢:Group By,Order by, having子句

MYSQL的高階查詢:Group By,Order by, having子句

1. Group by就是分組的意思,根據某個欄位進行分組。Group By 與 Count()函式 

基本語法:group by 欄位名;

使用前面的學生表,我們來進行練習

舉例:根據性別分組


根據上面顯示,我們使用了分組語句,結果出現了資料丟失的情況。分組之後男和女只顯示一條資料。

在SQL中分組是為了統計資料,SQL提供了一系列統計函式供我們使用。

1)      Count(): 統計分組後的記錄數,每一組有多少記錄

2)      Max(): 統計每組中最大值

3)      Min(): 統計最小值

4)      Avg(): 統計平均值。

5)      Sum(): 統計和

舉例:分組統計:身高高矮,年齡平均和總年齡


       上面表顯示男和女各有2個,男裡面最高175,女裡面最高165,還有後面的平均年齡和最矮身高。所以,如果你在SQL語句中使用了group by,但是沒有用到上面函式的一個或者幾個,那麼分組就沒有意義,就想我們文章開頭查詢的結果。

Count函式 

Count函式裡面可以使用兩種引數:*代表統計所有的記錄,使用欄位名 代表統計對應欄位(Null不統計)。

舉例: 下面我們先準備一個欄位為null,例如把其中一個學生age設定值為null。


然後分別用count(*)和count(age)分組查詢進行對比。


由於我們之前把lily這個女性的age設定成null,所以count(age)在女性分組裡的統計數顯示為1.

 

分組會自動根據分組欄位排序,預設升序。

基本語法:group by 欄位[ase 或者 desc];-- 效果是對分組的結果合併後進行排序

 

預設female排序在前,升序這裡當然是安裝字母順序,desc表示降序,效果就是男性在前,女性在後。

 

多欄位分組 

為了演示效果,我們給當前學生表新增一個班級欄位,效果如下。

 

下面先按照班級,然後按照性別進行分組


      上面可以看到java01班級有一個女,有一個男,java02班有一個女,也有一個男。這種情況可以實現,每個班級有多少個女和多少個男的統計。那麼可不可以統計,每個班級女的和男的叫什麼。

 

這裡有一個函式,叫group_concat(欄位),效果就像上面那樣

having子句和order by字句,和where字句一樣,是用來進行條件判斷的。Where是針對磁碟資料進行判斷,進入到記憶體之後,會進行分組操作,分組結果就需要Having來處理。有這麼一個結論,having能做where能做的幾乎所有事情,但是where卻不能做having能做的事情。Order by主要就是用來排序操作。

分組統計的結果或者說統計函式 having能夠使用

舉例:求出所有班級人數大於等於2的學生人數

       為了方便舉例,我們需要對前面的my_student表進行插入和修改資料,這裡推薦用SQLyog圖形化工具來操作,比命令列不容易出錯,具體效果如下。


       上面有三個班級的學生資訊。下面我們來看如何用having子句來查詢人數大於等於2的學生人數,事件上這個結果應該是java02和java01,因為上面表java02班才有3個學生,java01有兩個學生。


先是通過班級分組,然後對分組結果進行having字句判斷。

 

Having能夠使用欄位別名,where不能

       因為where是從磁碟取資料,而名字只可能是欄位名,別名是在欄位進入到記憶體之後才會產生。下面就是利用欄位別名舉例,total就是count(*)的別名。


Where和having總結,能夠使用where就使用where,因為會減少在記憶體裡出錯的概率,查詢效率也更高。

 

Orderby


Order by就是排序操作,根據某個欄位進行升序或者降序排序,依賴校對集。

基本語法:order by 欄位名[asc 或者 desc];-- 預設是asc升序

 

我們先來看看分組和排序的區別


第一個查詢是分組,三個班級,所以有三個分組顯示;第二個查詢就是全量的排序顯示,可以看到java01排最前,java02在中間,java03在最後。

 

多欄位排序

排序可以進行多欄位排序,先根據某個欄位進行排序,然後排序好的內容,將按照某個資料進行再次排序。

舉例:先根據班級排序,然後根據身高排序。


       上面是先班級排序,然後班級內部再根據身高排序。排在在web的介面經常看得到,例如根據商品名稱排序,根據商品價格排序,根據時間排序等。

3. Limit子句是一種限制結果的語句,通常是限制數量。

 只用來限制長度(資料量):limit資料量;

 舉例:查詢學生表中前兩條記錄

我們本來有6條學生記錄,使用limit 2就只查詢前面兩條記錄。

 

限制起始位置,限制數量:limit起始位置,長度;

舉例:還是和上面一樣,查詢前面兩個學生記錄,看看有什麼區別。

 

      上面第二種寫法,起始位置是從0開始的,所以結果是一樣的。下面我們來查詢從第三個記錄開始,長度限制為3.


       由於起始位置是從0開始,所以第三條記錄的起始位置就是2,長度為3,就是查詢結果限制為3條。這種場景,在實際專案中,最常見的使用場景就是列表分頁顯示。例如web系統有一個列表,預設一頁顯示20條記錄,第21條就採取分頁方式,這種方式,主要能為使用者節省查詢時間,提高伺服器的響應效率,減少資源浪費。

      這裡簡單提下,前端頁面分頁在資料庫層面查詢的實現是這樣的,使用者只需要點選頁碼,例如有1,2,3,4這樣的頁面選單,而對於伺服器來講,會根據使用者選擇的頁碼來獲取不同的資料,這個limit的語法是這樣的:limit offset,length;

Length:每頁顯示的數量,一般基本不變,一般頁面有20,40,80等

0fferset:計算公式是這樣的:offerset =(頁碼-1)*每頁顯示數量。

        這裡再舉例一個limit的例子,筆試中經常讓寫,成績最高的前5名,或者工資最多的前5名。這裡我們來查詢出學生表裡面身高最高的前3名。