9-匯總數據
9.1-聚集函數
在實際開發過程中,可能會遇到下面這些情況:
-
確定大于某個值的有多少行數據,比如游戲排行榜,查詢玩家排行多少名。
-
獲取表中某些行的和,比如雙十一當天,某個用戶總訂單價格是多少元。
-
獲取表中最大值,最小值,平均值。
上述這些例子只需要返回統計后的數值,而不需要返回所有數值,然后在進行統計,這么做節省了時間,提高了效率。
為了方便做類似上述例子的操作,SQL給出了五個函數。
?
9.1.1 avg()函數
avg()函數的執行過程:先對表中行數進行計算,然后求得某列的和,最后求取平均值。
例如:返回products表中的平均價格
select avg(prod_price) as avg_price
from products;
avg()也可以結合WHERE子句來確定特定的列或者行的平均值。
select avg(prod_price) as avg_price
from products
where vend_id = 'DLL01';
?
上述SQL語句是僅過濾供應商為‘DLL01’的產品的價格的平均值。
只用于單個列 AVG()只能用來確定特定數值列的平均值,而且列名必須作為函數參數給出。為了獲得多個列的平均值,必須使用多個AVG()函數。
注意:avg函數會忽略列值為NULL的行。
9.1.2 count()函數
count()函數是用來計數的。可利用count()確定表中行的數目或者符合規定的行的數目。
-
使用count(*) 對表中行的數目進行計數,不管表列中包含的是空值NULL還是非空值。
-
使用count(column)對特定列中具有值的行進行計數。忽略NULL值。
select count(*) as num_cust
from customers;
?
上述SQL語句查詢customers表中的顧客總數。count(*)對所有具有值的行進行計數,計算得到的值在num_cust中返回。
select count(cust_email) as num_cust
from customers;
?
上述SQL語句用于統計顧客表中擁有郵箱的顧客有多少,主動忽略了NULL值。
NULL值 如果指定列名,則COUNT()函數會忽略指定列的值為NULL的行,但如果COUNT()函數中用的是星號(*),則不忽略。
9.1.3 max()函數
max()函數返回指定列中的最大值。max()函數要指定列名。
select max(prod_price) as max_price
from products;
?
上述SQL語句是查詢產品列表中價格最高的產品。
max()函數一般用來找出最大的數值或者日期,但是有許多DBMS允許它返回任意列中的最大值,包括返回文本列中的最大值。當max()函數用于返回文本最大值時,返回按該列排序的最后一行。
max()函數忽略值為NULL的行。
9.1.4 min()函數
與max()函數相反,min()函數返回指定列的最小值。min()函數要求指定列名。
select min(prod_price) as min_price
from products;
?
min()函數一般用來找出最小的數值或者日期,但是有許多DBMS允許它返回任意列中的最小值,包括返回文本列中的最小值。當min()函數用于返回文本最小值時,返回按該列排序的最前面的行。
min()函數忽略NULL值所在的行。
9.1.5 sum()函數
sum()函數用來返回指定列值的總和。
例如:orderitems表中包含訂單中實際的物品,每個物品有相應的數量,由此計算所訂購的物品的總數。
select sum(quantity) as items_ordered
from orderitems
where order_num = 20005;
?
上述SQL語句用于返回總的物品數量,一共是200個。
函數SUM(quantity)返回訂單中所有物品數量之和,WHERE子句保證只統計某個物品訂單中的物品。
sum()也可以用來合計計算值。
select sum(item_price*quantity) as total_price
from orderitems
where order_num = 20005;
?
上述SQL語句計算所有符合條件的價值的總和。
sum()函數忽略列值為NULL的行。
9.2-聚集不同值
上述五種聚集函數都可以按照下面的方式使用:
-
對所有行執行計算,指定all參數或不指定參數(因為all是默認行為)。
-
只包含不同的值,指定distinct
注意:all參數不需要指定,它是默認行為。如果不指定distinct,則假定為all。
下面舉例說明指定distinct參數,而不使用默認參數。
select avg(distinct prod_price) as avg_price
from products
where vend_id = 'DLL01';
?
因為使用了distinct參數,所以計算平均值的時候自動忽略相同的價格去計算平均值。但是計算后高于上面我們計算的平均價格,這是因為數量雖然少了,但是價格低的物品數量也少了。
另外,distinct不能用于count(*),但是可以用于指定列名的count(),也就是說:如果想要使用distinct,就必須指定列名。
distinct可以用于min()和max(),但是毫無意義,因為只有一行。
9.3-組合聚集函數
select語句可以根據需要選擇多個聚合函數。
select count(*) as num_items,min(prod_price) as price_min,max(prod_price) as price_max,avg(prod_price) as price_avg
from products;
?
上述SQL語句返回products表中物品數量,產品價格最高,產品價格最低以及平均值。
練習
-
編寫SQL語句,確定已售出產品的總數(使用OrderItems中的quantity列)。
select sum(quantity) as selled from orderitems;
?
-
修改剛剛創建的語句,確定已售出產品項(prod_id)BR01的總數。
select sum(quantity) as selled from orderitems where prod_id = 'BR01';
?
-
編寫SQL語句,確定Products表中價格不超過10美元的最貴產品的價格(prod_price)。將計算所得的字段命名為max_price。
select max(prod_price) as max_price from products where prod_price <= 10;
?