1、定義
聚集函數(shù)是以值是一個集合(集或者多重集)為輸入、返回單個值得函數(shù)。SQL提供了五個固有聚集函數(shù)。
平均值:avg
最小值:min
最大值:max
總和:sum
計數(shù):count
2、基本聚集
以上五個固有聚集函數(shù)都是屬于基本聚集
示例:
-- 找出教師的平均工資
SELECT AVG (salary)
FROM instructor
其他基本聚集使用形式差不多。
--找出名字的個數(shù),這里的distinct作用是是的重復(fù)的元素不被計數(shù)
SELECT COUNT(DISTINCT name)
FROM instructor;
3、分組聚集
如果希望將聚集函數(shù)作用在單個元組集上,也希望作用到一組元組集上,此時可以利用group by子句來實現(xiàn)。
group by 子句作用:對給出的一個或多個屬性來構(gòu)造分組,將屬性上取值相同的元組分到同一組中。
示例:
# 找出每個系的教師平均工資
SELECT dept_name, avg(salary) AS avg_salary
FROM instructor
GROUP BY dept_name;
# 找出教師的平均工資,則是省略了group by,將整個關(guān)系當(dāng)成一個組別
SELECT AVG (salary)
FROM instructor
值得注意的是,當(dāng)SQL查詢使用分組的時候,需要保證出現(xiàn)在select語句中但沒有被聚集的屬性只能是出現(xiàn)在group by 子句中的那些屬性。換句話說,任何沒有出現(xiàn)在group by子句中的屬性如果出現(xiàn)在select子句中的話,它只能出現(xiàn)在聚集函數(shù)的內(nèi)部,否則這樣的查詢就是錯誤的,例如:
SELECT dept_name,id,avg(salary) as avg_salary
FROM instructor
GROUP BY dept_name;
不過令我哭笑不得是,呃……,竟然運行沒有報錯[捂臉.jpg],然后仔細(xì)觀察了以下,原因是id是沒有被聚集,所以是屬于查詢錯誤,
看下面的結(jié)果,類別biology的id只有10211,其實還有另外一個。在分組計算中只輸出一個元組,這樣是無法確定選擇哪一個id作為輸出,下一次運行結(jié)果id值可能為其他值。[如果你有什么新發(fā)現(xiàn),望告知]


4、having子句
有時候限定分組條件比對元組限定條件更有用。比如我們只對工資超過15000某一個系感興趣。該條件并不針對某個元組,而是針對group by子句構(gòu)成的分組。即是說,having子句是在分組之后才生效的,可以使用聚集函數(shù)。例如:
SELECT dept_name,avg(salary) as avg_salary
FROM instructor
GROUP BY dept_name
HAVING avg(salary)>15000;
注意:與select子句的情況類似,任何出現(xiàn)在having子句中,但沒有被聚集的屬性必須出現(xiàn)在group by子句中,否則查詢就被當(dāng)成是錯誤的。
包含聚集、group by 或者h(yuǎn)aving子句的查詢的含義可通過下述操作序列定義:
1、根據(jù)from子句計算出一個關(guān)系
2、如果出現(xiàn)where子句,where子句的謂詞將應(yīng)用到from子句的結(jié)果上
3、如果出現(xiàn)group by子句,滿足where子句的元組通過group by子句形成分組。如果沒有
group by子句,滿足where謂詞的整個元組集被當(dāng)做一個分組
4、如果出現(xiàn)having子句,他將應(yīng)用到每個分組上;不滿足having子句謂詞的分組將被拋棄。
5、select子句利用剩下的分組產(chǎn)生出查詢結(jié)果中的元組,即每個分組上應(yīng)用聚集函數(shù)來得到單個關(guān)系元組
5、對空值和布爾值的聚集
空值的出現(xiàn)對聚集運算帶來了麻煩,例如下列句子:
select sum(salary)
from instructor;
當(dāng)instructor關(guān)系有些元組在salary屬性的值為空,則在查詢待求和的值中就包含了空值。SQL標(biāo)準(zhǔn)并不認(rèn)為總和本身為null,而是認(rèn)為sum運算符應(yīng)忽略輸入中的null值(因為算術(shù)表達(dá)式如果有null,那么結(jié)果為null)。
所以,聚集函數(shù)根據(jù)以下原則處理空值:
除了count(*)外,所有的聚集函數(shù)都忽略輸入集合中的空值。由于空值被忽略,可能會造成參加聚集函數(shù)的輸入值集合為空集。規(guī)定空集的count運算值為0,其他所有聚集運算在輸入為空集的情況下返回一個空值。
處理布爾值的聚集函數(shù):some 和every。
從字面意義上就可以知道,some是只要滿足其中任意一個條件即可,而every則是所有條件都要滿足,比如說1=some(集合A),若A={1,2,3},則為真,若A={0,2,3}則為假,又如1>some(集合A),結(jié)果分別為假、真。
例如:
#該示例是將表instructor根據(jù)dept_name分組,
#用having子句判斷dept_name是否在關(guān)系表department中,
#然后select dept_name,和avg(salary);
SELECT dept_name,avg(salary) as avg_salary
FROM instructor
GROUP BY dept_name
HAVING dept_name = SOME (SELECT dept_name FROM department)



