1. 程式人生 > 其它 >SQL——聚集函式

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 子句中的那些屬性。換句話說,任何沒有出現

在group by子句中的屬性如果出現在select子句中的話,它只能出現在聚集函式的內部,否則這樣的查詢就是錯誤的,例如:

SELECT dept_name,id,avg(salary) as avg_salary
FROM instructor
GROUP BY dept_name;

不過令我哭笑不得是,呃……,竟然執行沒有報錯[捂臉.jpg],然後仔細觀察了以下,原因是id是沒有被聚集,所以是屬於查詢錯誤,
看下面的結果,類別biology的id只有10211,其實還有另外一個。在分組計算中只輸出一個元組,這樣是無法確定選擇哪一個id作為輸出,下一次執行結果id值可能為其他值。[如果你有什麼新發現,望告知]

  dept_name ||    id       || avg_salary null               10215      14400 biology          10211      66000 history           10213      12000 結果表  id            ||    dept_name || salary || name  10211         biology           66000     smith 10212        biology            66000     handsome 10213         history            12000     google 10214         hitstory           12000     smith 10215        null                  14400     wu 原表

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
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。