RSS订阅
PHP程序员站--WWW.PHPERZ.COM  
网站地图
高级搜索
收藏本站

 当前位置:主页 >> 数据库 >> MySQL >> 文章内容
在数据库中 如何进行分类分组并总计SQL信息
[收藏此页[打印本页]   
来源:互联网  作者:Builder.com.cn  发布时间:2007-12-24

 

您需要了解如何使用某些SQL子句和运算符来安排SQL数据,从而对它进行高效分析。下面这些建议告诉您如何建立语句,获得您希望的结果。 www.phperz.com

以有意义的方式安排数据可能是一种挑战。有时您只需进行简单分类。通常您必须进行更多处理——进行分组以利于分析与总计。可喜的是,SQL提供了大量用于分类、分组和总计的子句及运算符。下面的建议将有助于您了解何时进行分类、何时分组、何时及如何进行总计。欲了解每个子句和运算符的详细信息,请查看在线书籍

phperz.com

#1:分类排序

www~phperz~com

通常,我们确实需要对所有数据进行排序。SQL的ORDER BY子句将数据按字母或数字顺序进行排列。因此,同类数据明显分类到各个组中。然而,这些组只是分类的结果,它们并不是真正的组。ORDER BY显示每一个记录,而一个组可能代表多个记录。 www~phperz~com

#2:减少组中的相似数据 www.phperz.com

分类与分组的最大不同在于:分类数据显示(任何限定标准内的)所有记录,而分组数据不显示这些记录。GROUP BY子句减少一个记录中的相似数据。例如,GROUP BY能够从重复那些值的源文件中返回一个唯一的邮政编码列表: www~phperz~com

SELECT ZIP php程序员站

FROM Customers

phperz.com

GROUP BY ZIP

www.phperz.com

仅包括那些在GROUP BY和SELECT列列表中字义组的列。换句话说,SELECT列表必须与GROUP列表相匹配。只有一种情况例外:SELECT列表能够包含聚合函数。(而GROUP BY不支持聚合函数。)

phperz.com

记住,GROUP BY不会对作为结果产生的组分类。要对组按字母或数字顺序排序,增加一个ORDER BY子句(#1)。另外,在GROUP BY子句中您不能引用一个有别名的域。组列必须在根本数据中,但它们不必出现在结果中。

phperz~com

#3:分组前限定数据 phperz.com

您可以增加一个WHERE子句限定由GROUP BY分组的数据。例如,下面的语句仅返回肯塔基地区顾客的邮政编码列表。

php程序员站

SELECT ZIP

php程序员之家

FROM Customers phperz~com

WHERE State = 'KY'

www.phperz.com

GROUP BY ZIP

www~phperz~com

在GROUP BY子句求数据的值之前,WHERE对数据进行过滤,记住这一点很重要。

php程序员站

和GROUP BY一样,WHERE不支持聚合函数。 php程序员站

#4:返回所有组

php程序员站

当您用WHERE过滤数据时,得到的组只显示那些您指定的记录。符合组定义但不满足子句条件的数据将不会出现在组中。不管WHERE条件如何,如果您想包括所有数据,增加一个ALL子句。例如,在前面的语句中增加一个ALL子句会返回所有邮政编码组,而不仅仅是肯塔基地区的组。 php程序员站

SELECT ZIP

www.phperz.com

FROM Customers

www~phperz~com

WHERE State = 'KY' phperz.com

GROUP BY ALL ZIP

php程序员站

照这个样子,这两个子句会造成冲突,您可能不会以这种方式使用ALL子句。当您用聚合求一个列的值时,应用ALL子句很方便。例如,下面的语句计算每个肯塔基邮政编码的顾客数目,同时显示其它邮政编码值。 www~phperz~com

SELECT ZIP, Count(ZIP) AS KYCustomersByZIP php程序员之家

FROM Customers

www.phperz.com

WHERE State = 'KY'

www.phperz.com

GROUP BY ALL ZIP

www~phperz~com

得到的组由根本数据中的所有邮政编码值构成。但是,聚合列(KYCustomerByZIP)显示为0,因为除肯塔基邮政编码组外没有别的组。

www.phperz.com

远程查询不支持GROUP BY ALL。

php程序员站

#5:分组后限定数据 phperz.com

WHERE子句(#3)在GROUP BY子句之前求数据的值。当您希望在分组以后限定数据时,使用HAVING。通常,不管您使用WHERE还是HAVING,得到的结果相同。但要记住,这两个子句不能互换,这点很重要。如果您存在疑问,这里有一条应用指南:过滤记录时使用WHERE;过滤组时使用HAVING。 phperz~com

一般,您会用HAVING,利用聚合来求一个组的值。例如,下面的语句返回一个邮政编码列表,但这个表内可能不包含根本数据源中的每个邮政编码: www.phperz.com

SELECT ZIP, Count(ZIP) AS CustomersByZIP php程序员站

FROM Customers php程序员站

GROUP BY ZIP

phperz.com

HAVING Count(ZIP) = 1 phperz.com

仅仅那些只有一名顾客的组出现在结果中。

php程序员之家

#6:详细了解WHERE和HAVING www.phperz.com

如果您仍然对WHERE和HAVING的用法感到迷惑,应用下面的指导方法: www.phperz.com

WHERE出现在GROUP BY之前;SQL在它分组记录前求WHERE子句的值。
HAVING出现在GROUP BY之后;SQL在它分组记录后求HAVING子句的值。

phperz~com

#7:用聚合总计分组值

phperz~com

分组数据有助于对数据进行分析,但有时您还需要组本身以外的其它信息。您可以增加一个聚合函数来总计分组数据。例如,下面的语句为每次排序显示一个小计: phperz.com

SELECT OrderID, Sum(Cost * Quantity) AS OrderTotal php程序员之家

FROM Orders phperz.com

GROUP BY OrderID

php程序员站

与其它的组一样,SELECT和GROUP BY列表必须相匹配。在SELECT子句中包含一个聚合是这一规则的唯一例外。 php程序员站

#8:总计聚合 php程序员站

您可以通过显示每个组的小计进一步总计数据。SQL的ROLLUP运算符为每个组显示一个额外的记录,一个小计。那个记录是用聚合函数在每个组中求所有记录的值的结果。下面的语句为每个组合计OrderTotal列。 php程序员站

SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotal www~phperz~com

FROM Orders

www~phperz~com

GROUP BY Customer, OrderNumber php程序员站

WITH ROLLUP

www.phperz.com

一个包含20和25这两个OrderTotal值的组的ROLLUP行将显示OrderTotal值45。ROLLUP结果的第一个值是唯一的,因为它求所有组记录的值。那个值是整个记录集的总和。

phperz.com

ROLLUP不支持聚合函数中的DISTINCT或GROUP BY ALL子句。

www.phperz.com

#9:总计每一列

php程序员之家

CUBE运算符比ROLLUP更进一步,它返回每个组中每个值的总数。得到的结果与ROLLUP相似,但CUBE包括组中每一列的一个额外记录。下面的语句显示每个组的小计和每名顾客的一个额外总数。 php程序员站

SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotal php程序员站

FROM Orders phperz~com

GROUP BY Customer, OrderNumber php程序员站

WITH CUBE

php程序员站

用CUBE得到的总计最为复杂。不仅完成聚合与ROLLUP的工作,而且还求定义组的其它列的值。也就是说,CUBE总计每一个可能的列组合。 www~phperz~com

CUBE不支持GROUP BY ALL。

phperz.com

#10:给总计排序 www.phperz.com

当CUBE的结果杂乱无章时(一般都是这样),可以增加一个GROUPING函数,如下所示:

php程序员之家

SELECT GROUPING(Customer), OrderNumber, Sum(Cost * Quantity) AS OrderTotal www~phperz~com

FROM Orders

www~phperz~com

GROUP BY Customer, OrderNumber

phperz.com

WITH CUBE www.phperz.com

其结果包括每一行的两个额外的值。

php程序员站

值1表明左边的值是一个总计值——ROLLUP或CUBE的运算符的结果。
值0表明左边的值是一个原始GROUP BY子句产生的详细记录。 www.phperz.com


 
 相关文章
 
发表评论
全部评论(0条)
 
 站内搜索
 热门搜索 基础  mysql  url  adodb
高级搜索 网站地图 站长工具 IP查询 收藏本站
 热点文章
 随机推荐
网站首页 | 网站地图 | 高级搜索 | RSS订阅
PHP程序员站 Copyright © 2007,PHPERZ.COM All Rights Reserved 粤ICP备07503606号 联系站长