MySQL(五)匯總和分組數據


一、匯總數據

工作中經常需要匯總數據而不是將它們全部檢索出來(實際數據本身:返回實際數據是對時間和處理資源的浪費),這種類型的檢索有以下特點:

確定表中的行數(或者滿足某個條件或包含某個特定值的行數)

獲得表中行組的和

找出表列(或所有行或某些特定的行)的最大值、最小值和平均值

聚集函數(aggregate function):運行在行組上,計算和返回單個值的函數(MySQL還支持一些列的標准偏差聚集函數);

SQL聚集函數如下表:

 

1、avg()函數

avg()通過對表中行數計數並計算特定列值之和,求得該列的平均值;avg()可用來返回所有列平均值,也可用來返回特定列的平均值;

select avg(prod_price) as avg_price from pfoducts;

此select語句返回值avg_price,它包含producs表中所有產品的平均價格,avg_price是一個別名;

avg()也可以用來確定特定列或行的平均值,例子如下:

select avg_(prod_price) as avg_price from products where vend_id = 1003;

這條SQL語句包含了where子語句,僅過濾出vend_id為1003的產品,avg_price中返回該供應商的產品的平均值;

PS:avg()只能用來確定特定數值列的平均值,而且列名必須作為函數參數給出,為了獲得多個列的平均值,必須使用多個avg()函數{avg()函數忽略列值為NULL的行};

 

2、count()函數

count()函數進行計數,可利用count()確定表中行的數目或符合特定條件的行的數目;

count()函數有兩種使用方式:

使用count(*)對表中行的數目進行計數,不管表列中包含的是空值(null)還是非空值;

使用count(column)對特定列中具有值的行進行計數,忽略null值;

select count(*) as num_cust from customers;

這條SQL語句利用count(*)對customers表中所有行計數,計數值在num_cust中返回;

select count(cust_email) as cum_cust from customers;

這條SQL語句使用count(cust_email)對cust_email列中有值的行進行計數;

PS:如果指定列名,則指定列的值為空的行被count()函數忽略,但如果count()函數中用的是星號(*),則不忽略; 

 

3、max()函數

max()返回指定列中的最大值,max()要求指定列名,例子如下:

select max(prod_price) as max_price from products;

這條SQL語句中國返回products表中price列的最大值;

PS:MySQL允許max()用來返回任意列中的最大值,包括返回文本列的最大值;但用於文本數據時,如果數據按相應的列排序,則max()返回最后一行(max()函數忽略列值為null的行)

 

4、min()函數

min()返回指定列的最小值,min()也要求指定列名,例子如下:

select min(prod_price) as min_price from products;

這條SQL語句中min()返回products表中price列最小值;

PS:MySQL允許min()用來返回任意列中的最小值,包括返回文本列的最小值;但用於文本數據時,如果數據按相應的列排序,則min()返回最前面的行(min()函數忽略列值為null的行)

 

5、sum()函數

sum()函數用來返回指定列值的和(總計);例子如下:

select sum(quantity) as items_ordered from orderitems where order_num = 20005;

函數sum()返回orderitems中所有quantity列的值之和,where子句保證只統計某個指定列的數值;

PS:利用標准的算數操作符,所有聚集函數都可用來執行多個列上的計算(sum()函數忽略列值為null的行)

 

6、distinct與聚集函數

MySQL5.0.3以及之后的版本,聚集函數和distinct可以搭配使用,比如:

對所有的行執行計算,指定all參數或不給參數(all是默認所有行為,不需要指定,如果不指定distinct,則假定為all);

只包含不同的值,指定distinct參數;

如果指定列名,則distinct只能用於count();distinct不能用於count(*),因此不允許使用count(distinct);distinct必須使用列名,不能用於計算或者表達式;

select avg(distinct prod_price) as avg_price from products where vend_id = 1003;

這條SQL語句中,使用avg()函數返回vend列中vend_id=1003的對應的price平均價格,因為使用了distinct參數,因此平均值只考慮不同的值(唯一值)

 

7、組合聚集函數

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語句,使用了單條select語句執行4個聚集計算,返回四個值(products表中items的數目、price的最高、最低以及平均值)

PS:在指定別名以包含某個聚集函數的結果時,不應該使用表中實際的列名;這樣便於使用SQL更加容易和理解,以及排除方便排除錯誤。

 

二、分組數據

1、group by創建分組

在MySQL中,分組是在select語句中的group by子句中建立的,比如:

select vend-id,count(*) as num_prods from products group by vend_id;

這條SQL語句指定了2個列,group by指示MySQL按照vend_id排序並且分組(如果使用group by,則不必指定要計算的每個組)

group by子句指示指示MySQL分組數據,然后都每個組而不是整個結果集進行聚集;關於group by使用,請注意以下規則:

group by子句可以包含任意數目的列(使得對分組進行嵌套,為數據分組提供更細致的控制);

如果在group by子句中嵌套分組,數據將在最后規定的分組上進行匯總,即:建立分組時,指定的所有列都一起計算(所以不能從個別列取回數據);

group by子句中列出的每個列都必須是檢索列或有效的表達式(但不能是聚集函數),如果在select中使用表達式,則必須在group by子句中指定相同的表達式(不能使用別名);

除了聚集計算語句外,select中每個列都必須在group by子句中給出;

如果分組列中具有null值,則null將作為一個分組返回(如果列中有多行null值,他們將分為一組);

group by子句必須出現在where子句之后,order by子句之前;

PS:使用with rollup關鍵字,可以得到每個分組以及每個分組匯總級別(針對每個分組)的值。

 

2、having過濾分組

where子句都可以用having代替,區別在於where過濾行,having過濾分組;having支持所有的where操作符,比如:

select cust_id,count(*) as orders from orders group by cust_id having count(*) >= 2;

這條SQL語句中的having子句過濾count(*)>=2(2個以上的分組)的那些分組;

having和where的區別:

where在數據分組前進行過濾,having在數據分組后進行過濾;where排除的行不包括在分組中(這可能會改變計算值,從而影響having子句中基於這些值過濾掉的分組)

having和where可以同時使用,比如:

select vend_id, count(*) as num_prods from products where prod_price>=10 group by vend_id having count(*)>= 2;

這條SQL語句中,where子句過濾掉所有prod_price至少為10的行,然后按照vend_id分組數據;having子句過濾技術為2或2以上的分組;

 

3、分組和排序

group by和order by的區別:

order by的重要性:一般使用group by子句時,應該也給出order by子句,這是保證數據正確性的唯一方法(千萬不要依賴group by排序數據)。

 

4、select子句順序

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM