到現在為止,你隻學習瞭如何根據特定的條件從表中取出一條或多條記錄。但是,假如你想對一個表中的記錄進行數據統計。例如,如果你想統計存儲在表中的一次民意測驗的投票結果。或者你想知道一個訪問者在你的站點上平均花費瞭多少時間。要對表中的任何類型的數據進行統計,都需要使用集合函數。你可以統計記錄數目,平均值,最小值,最大值,或者求和。當你使用一個集合函數時,它隻返回一個數,該數值代表這幾個統計值之一。
這些函數的最大特點就是經常和GROUP BY語句配合使用,需要註意的是集合函數不能和非分組的列混合使用。
行列計數
計算查詢語句返回的記錄行數
直接計算函數COUNT(*)的值,例如,計算pet表中貓的隻數:
mysql>SELECT count(*) FROM pet WHERE species=’cat’;
+———-+
| count(*) |
+———-+
| 2 |
+———-+
統計字段值的數目
例如,計算pet表中species列的數目:
mysql> SELECT count(species) FROM pet;
+—————-+
| count(species) |
+—————-+
| 9 |
+—————-+
如果相同的種類出現瞭不止一次,該種類將會被計算多次。如果你想知道種類為某個特定值的寵物有多少個,你可以使用WHERE子句,如下例所示:
mysql> SELECT COUNT(species) FROM pet WHERE species=cat ;
註意這條語句的結果:
+—————-+
| COUNT(species) |
+—————-+
| 2 |
+—————-+
這個例子返回種類為cat的作者的數目。如果這個名字在表pet中出現瞭兩次,則次函數的返回值是2。 而且它和上面提到過的語句的結果是一致的:
SELECT count(*) FROM pet WHERE species=’cat’
實際上,這兩條語句是等價的。
假如你想知道有多少不同種類的的寵物數目。你可以通過使用關鍵字DISTINCT來得到該數目。如下例所示:
mysql> SELECT COUNT(DISTINCT species) FROM pet;
+————————-+
| COUNT(DISTINCT species) |
+————————-+
| 5 |
+————————-+
如果種類cat出現瞭不止一次,它將隻被計算一次。關鍵字DISTINCT 決定瞭隻有互不相同的值才被計算。
通常,當你使用COUNT()時,字段中的空值將被忽略。
另外,COUNT()函數通常和GROUP BY子句配合使用,例如可以這樣返回每種寵物的數目:
mysql> SELECT species,count(*) FROM pet GROUP BY species;
+———+———-+
| species | count(*) |
+———+———-+
| bird | 2 |
| cat | 2 |
| dog | 3 |
| hamster | 1 |
| snake | 1 |
+———+———-+
計算字段的平均值
需要計算這些值的平均值。使用函數AVG(),你可以返回一個字段中所有值的平均值。
假如你對你的站點進行一次較為復雜的民意調查。訪問者可以在1到10之間投票,表示他們喜歡你站點的程度。你把投票結果保存在名為vote的INT型字段中。要計算你的用戶投票的平均值,你需要使用函數AVG():
SELECT AVG(vote) FROM opinion
這個SELECT語句的返回值代表用戶對你站點的平均喜歡程度。函數AVG()隻能對數值型字段使用。這個函數在計算平均值時也忽略空值。
再給出一個實際例子,例如我們要計算pet表中每種動物年齡的平均值,那麼使用AVG()函數和GROUP BY子句:
mysql> SELECT species,AVG(CURDATE()-birth) FROM pet GROUP BY species;
返回的結果為:
+———+———————-+
| species | AVG(CURDATE()-birth) |
+———+———————-+
| bird | 34160 |
| cat | 74959.5 |
| dog | 112829.66666667 |
| hamster | 19890 |
| snake | 49791 |
+———+———————-+
計算字段值的和
假設你的站點被用來出售某種商品,已經運行瞭兩個月,是該計算賺瞭多少錢的時候瞭。假設有一個名為orders的表用來記錄所有訪問者的定購信息。要計算所有定購量的總和,你可以使用函數SUM():
SELECT SUM(purchase_amount) FROM orders
函數SUM()的返回值代表字段purchase_amount中所有值的總和。字段purchase_amount的數據類型也許是DECIMAL類型,但你也可以對其它數值型字段使用函數SUM()。
用一個不太恰當的例子說明,我們計算pet表中同種寵物的年齡的總和:
mysql> SELECT species,SUM(CURDATE()-birth) FROM pet GROUP BY species;
你可以查看結果,與前一個例子對照:
+———+———————-+
| species | SUM(CURDATE()-birth) |
+———+———————-+
| bird | 68320 |
| cat | 149919 |
| dog | 338489 |
| hamster | 19890 |
| snake | 49791 |
+———+———————-+
計算字段值的極值
求字段的極值,涉及兩個函數MAX()和MIN()。
例如,還是pet表,你想知道最早的動物出生日期,由於日期最早就是最小,所以可以使用MIN()函數:
mysql> SELECT MIN(birth) FROM pet;
+————+
| MIN(birth) |
+————+
| 1989-05-13 |
+————+
但是,你隻知道瞭日期,還是無法知道是哪隻寵物,你可能想到這樣做:
SELECT name,MIN(birth) FROM pet;
但是,這是一個錯誤的SQL語句,因為集合函數不能和非分組的列混合使用,這裡name列是沒有分組的。所以,你無法同時得到name列的值和birth的極值。
MIN()函數同樣可以與GROUP BY子句配合使用,例如,找出每種寵物中最早的出生日期:
mysql> SELECT species,MIN(birth) FROM pet GROUP BY species;
下面是令人滿意的結果:
+———+————+
| species | MIN(birth) |
+———+————+
| bird | 1997-12-09 |
| cat | 1993-02-04 |
| dog | 1989-05-13 |
| hamster | 1999-03-30 |
| snake | 1996-04-29 |
+———+————+
另一方面,如果你想知道最近的出生日期,就是日期的最大值,你可以使用MAX()函數,如下例所示:
mysql> SELECT species,MAX(birth) FROM pet GROUP BY species;
+———+————+
| species | MAX(birth) |
+———+————+
| bird | 1998-09-11 |
| cat | 1994-03-17 |
| dog | 1990-08-31 |
| hamster | 1999-03-30 |
| snake | 1996-04-29 |
+———+————+
總結
在本節中,介紹瞭一些典型的集合函數的用法,包括計數、均值、極值和總和,這些都是SQL語言中非常常用的函數。
這些函數之所以稱之為集合函數,是因為它們應用在多條記錄中,所以集合函數最常見的用法就是與GROUP BY子句配合使用,最重要的是集合函數不能同未分組的列混合使用。