SQL——聚集函式
1、定義
聚集函式是以值是一個集合(集或者多重集)為輸入、返回單個值得函式。SQL提供了五個固有聚集函式。
平均值:avg
最小值:min
最大值:max
總和:sum
計數:count
2、基本聚集
以上五個固有聚集函式都是屬於基本聚集
示例:
-- 找出教師的平均工資
SELECT AVG (salary)
FROM instructor
其他基本聚集使用形式差不多。
--找出名字的個數,這裡的distinct作用是是的重複的元素不被計數
SELECT COUNT(DISTINCT name)
FROM instructor;
3、分組聚集
如果希望將聚集函式作用在單個元組集上,也希望作用到一組元組集上,此時可以利用group by子句來實現。
group by 子句作用:對給出的一個或多個屬性來構造分組,將屬性上取值相同的元組分到同一組中。
示例:
# 找出每個系的教師平均工資
SELECT dept_name, avg(salary) AS avg_salary
FROM instructor
GROUP BY dept_name;
# 找出教師的平均工資,則是省略了group by,將整個關係當成一個組別
SELECT AVG (salary)
FROM instructor
值得注意的是,當SQL查詢使用分組的時候,需要保證出現在select語句中但沒有被聚集的屬性只能是出現在group by 子句中的那些屬性。換句話說,任何沒有出現
SELECT dept_name,id,avg(salary) as avg_salary
FROM instructor
GROUP BY dept_name;
不過令我哭笑不得是,呃……,竟然執行沒有報錯[捂臉.jpg],然後仔細觀察了以下,原因是id是沒有被聚集,所以是屬於查詢錯誤,
看下面的結果,類別biology的id只有10211,其實還有另外一個。在分組計算中只輸出一個元組,這樣是無法確定選擇哪一個id作為輸出,下一次執行結果id值可能為其他值。[如果你有什麼新發現,望告知]
4、having子句
有時候限定分組條件比對元組限定條件更有用。比如我們只對工資超過15000某一個系感興趣。該條件並不針對某個元組,而是針對group by子句構成的分組。即是說,having子句是在分組之後才生效的,可以使用聚集函式。例如:
SELECT dept_name,avg(salary) as avg_salary
FROM instructor
GROUP BY dept_name
HAVING avg(salary)>15000;
注意:與select子句的情況類似,任何出現在having子句中,但沒有被聚集的屬性必須出現在group by子句中,否則查詢就被當成是錯誤的。
包含聚集、group by 或者having子句的查詢的含義可通過下述操作序列定義:
1、根據from子句計算出一個關係
2、如果出現where子句,where子句的謂詞將應用到from子句的結果上
3、如果出現group by子句,滿足where子句的元組通過group by子句形成分組。如果沒有
group by子句,滿足where謂詞的整個元組集被當做一個分組
4、如果出現having子句,他將應用到每個分組上;不滿足having子句謂詞的分組將被拋棄。
5、select子句利用剩下的分組產生出查詢結果中的元組,即每個分組上應用聚集函式來得到單個關係元組
5、對空值和布林值的聚集
空值的出現對聚集運算帶來了麻煩,例如下列句子:
select sum(salary)
from instructor;
當instructor關係有些元組在salary屬性的值為空,則在查詢待求和的值中就包含了空值。SQL標準並不認為總和本身為null,而是認為sum運算子應忽略輸入中的null值(因為算術表示式如果有null,那麼結果為null)。
所以,聚集函式根據以下原則處理空值:
除了count(*)外,所有的聚集函式都忽略輸入集合中的空值。由於空值被忽略,可能會造成參加聚集函式的輸入值集合為空集。規定空集的count運算值為0,其他所有聚集運算在輸入為空集的情況下返回一個空值。
處理布林值的聚集函式:some 和every。
從字面意義上就可以知道,some是隻要滿足其中任意一個條件即可,而every則是所有條件都要滿足,比如說1=some(集合A),若A={1,2,3},則為真,若A={0,2,3}則為假,又如1>some(集合A),結果分別為假、真。
例如:
#該示例是將表instructor根據dept_name分組,
#用having子句判斷dept_name是否在關係表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)
dept_name ||avg_salary
null 14400
biology 66000
history 12000
沒有加having子句
dept_name || avg_salary
biology 66000
history 12000
加了having子句
dept_name ||building ||budget
biology 2333 12
history 2333 12
math 6666 15
phisics 3333 12
sb 6666 22
department表
id ||dept_name ||salary ||name
10211 biology 66000 smith
10212 biology 66000 handsome
10213 history 12000 google
10214 history 12000 smith
10215 null 14400 wu
作者:薛定諤與貓的故事
連結:https://www.jianshu.com/p/5e1f9b8a2ec9
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。