在數(shù)據(jù)庫中 如何進行分類分組并總計SQL信息
發(fā)布時間: 2006-11-23 09:23 作者: Builder.com.cn 信息來源: Builder.com.cn
您需要了解如何使用某些SQL子句和運算符來安排SQL數(shù)據(jù),從而對它進行高效分析。下面這些建議告訴您如何建立語句,獲得您希望的結(jié)果。 以有意義的方式安排數(shù)據(jù)可能是一種挑戰(zhàn)。有時您只需進行簡單分類。通常您必須進行更多處理——進行分組以利于分析與總計。可喜的是,SQL提供了大量用于分類、分組和總計的子句及運算符。下面的建議將有助于您了解何時進行分類、何時分組、何時及如何進行總計。欲了解每個子句和運算符的詳細信息,請查看在線書籍。 #1:分類排序 通常,我們確實需要對所有數(shù)據(jù)進行排序。SQL的ORDER BY子句將數(shù)據(jù)按字母或數(shù)字順序進行排列。因此,同類數(shù)據(jù)明顯分類到各個組中。然而,這些組只是分類的結(jié)果,它們并不是真正的組。ORDER BY顯示每一個記錄,而一個組可能代表多個記錄。 #2:減少組中的相似數(shù)據(jù) 分類與分組的最大不同在于:分類數(shù)據(jù)顯示(任何限定標(biāo)準內(nèi)的)所有記錄,而分組數(shù)據(jù)不顯示這些記錄。GROUP BY子句減少一個記錄中的相似數(shù)據(jù)。例如,GROUP BY能夠從重復(fù)那些值的源文件中返回一個唯一的郵政編碼列表: SELECT ZIP FROM Customers GROUP BY ZIP 僅包括那些在GROUP BY和SELECT列列表中字義組的列。換句話說,SELECT列表必須與GROUP列表相匹配。只有一種情況例外:SELECT列表能夠包含聚合函數(shù)。(而GROUP BY不支持聚合函數(shù)。) 記住,GROUP BY不會對作為結(jié)果產(chǎn)生的組分類。要對組按字母或數(shù)字順序排序,增加一個ORDER BY子句(#1)。另外,在GROUP BY子句中您不能引用一個有別名的域。組列必須在根本數(shù)據(jù)中,但它們不必出現(xiàn)在結(jié)果中。 #3:分組前限定數(shù)據(jù) 您可以增加一個WHERE子句限定由GROUP BY分組的數(shù)據(jù)。例如,下面的語句僅返回肯塔基地區(qū)顧客的郵政編碼列表。 SELECT ZIP FROM Customers WHERE State = ‘KY‘ GROUP BY ZIP 在GROUP BY子句求數(shù)據(jù)的值之前,WHERE對數(shù)據(jù)進行過濾,記住這一點很重要。 和GROUP BY一樣,WHERE不支持聚合函數(shù)。 #4:返回所有組 當(dāng)您用WHERE過濾數(shù)據(jù)時,得到的組只顯示那些您指定的記錄。符合組定義但不滿足子句條件的數(shù)據(jù)將不會出現(xiàn)在組中。不管WHERE條件如何,如果您想包括所有數(shù)據(jù),增加一個ALL子句。例如,在前面的語句中增加一個ALL子句會返回所有郵政編碼組,而不僅僅是肯塔基地區(qū)的組。 SELECT ZIP FROM Customers WHERE State = ‘KY‘ GROUP BY ALL ZIP 照這個樣子,這兩個子句會造成沖突,您可能不會以這種方式使用ALL子句。當(dāng)您用聚合求一個列的值時,應(yīng)用ALL子句很方便。例如,下面的語句計算每個肯塔基郵政編碼的顧客數(shù)目,同時顯示其它郵政編碼值。 SELECT ZIP, Count(ZIP) AS KYCustomersByZIP FROM Customers WHERE State = ‘KY‘ GROUP BY ALL ZIP 得到的組由根本數(shù)據(jù)中的所有郵政編碼值構(gòu)成。但是,聚合列(KYCustomerByZIP)顯示為0,因為除肯塔基郵政編碼組外沒有別的組。 遠程查詢不支持GROUP BY ALL。 #5:分組后限定數(shù)據(jù) WHERE子句(#3)在GROUP BY子句之前求數(shù)據(jù)的值。當(dāng)您希望在分組以后限定數(shù)據(jù)時,使用HAVING。通常,不管您使用WHERE還是HAVING,得到的結(jié)果相同。但要記住,這兩個子句不能互換,這點很重要。如果您存在疑問,這里有一條應(yīng)用指南:過濾記錄時使用WHERE;過濾組時使用HAVING。 一般,您會用HAVING,利用聚合來求一個組的值。例如,下面的語句返回一個郵政編碼列表,但這個表內(nèi)可能不包含根本數(shù)據(jù)源中的每個郵政編碼: SELECT ZIP, Count(ZIP) AS CustomersByZIP FROM Customers GROUP BY ZIP HAVING Count(ZIP) = 1 僅僅那些只有一名顧客的組出現(xiàn)在結(jié)果中。 #6:詳細了解WHERE和HAVING 如果您仍然對WHERE和HAVING的用法感到迷惑,應(yīng)用下面的指導(dǎo)方法: WHERE出現(xiàn)在GROUP BY之前;SQL在它分組記錄前求WHERE子句的值。 #7:用聚合總計分組值 分組數(shù)據(jù)有助于對數(shù)據(jù)進行分析,但有時您還需要組本身以外的其它信息。您可以增加一個聚合函數(shù)來總計分組數(shù)據(jù)。例如,下面的語句為每次排序顯示一個小計: SELECT OrderID, Sum(Cost * Quantity) AS OrderTotal FROM Orders GROUP BY OrderID 與其它的組一樣,SELECT和GROUP BY列表必須相匹配。在SELECT子句中包含一個聚合是這一規(guī)則的唯一例外。 #8:總計聚合 您可以通過顯示每個組的小計進一步總計數(shù)據(jù)。SQL的ROLLUP運算符為每個組顯示一個額外的記錄,一個小計。那個記錄是用聚合函數(shù)在每個組中求所有記錄的值的結(jié)果。下面的語句為每個組合計OrderTotal列。 SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotal FROM Orders GROUP BY Customer, OrderNumber WITH ROLLUP 一個包含20和25這兩個OrderTotal值的組的ROLLUP行將顯示OrderTotal值45。ROLLUP結(jié)果的第一個值是唯一的,因為它求所有組記錄的值。那個值是整個記錄集的總和。 ROLLUP不支持聚合函數(shù)中的DISTINCT或GROUP BY ALL子句。 #9:總計每一列 CUBE運算符比ROLLUP更進一步,它返回每個組中每個值的總數(shù)。得到的結(jié)果與ROLLUP相似,但CUBE包括組中每一列的一個額外記錄。下面的語句顯示每個組的小計和每名顧客的一個額外總數(shù)。 SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotal FROM Orders GROUP BY Customer, OrderNumber WITH CUBE 用CUBE得到的總計最為復(fù)雜。不僅完成聚合與ROLLUP的工作,而且還求定義組的其它列的值。也就是說,CUBE總計每一個可能的列組合。 CUBE不支持GROUP BY ALL。 #10:給總計排序 當(dāng)CUBE的結(jié)果雜亂無章時(一般都是這樣),可以增加一個GROUPING函數(shù),如下所示: SELECT GROUPING(Customer), OrderNumber, Sum(Cost * Quantity) AS OrderTotal FROM Orders GROUP BY Customer, OrderNumber WITH CUBE 其結(jié)果包括每一行的兩個額外的值。 值1表明左邊的值是一個總計值——ROLLUP或CUBE的運算符的結(jié)果。 |
|