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

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

 

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

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

PHP程序员站--PHP程序员之家

#1:分类排序 PHP程序员站--PHP程序员之家

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

PHP程序员站--PHP程序员之家

#2:减少组中的相似数据 PHP程序员站

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

SELECT ZIP PHP程序员站--PHP程序员之家

FROM Customers

PHP程序员站

GROUP BY ZIP

www phperz com

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

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

www.phperz.com

#3:分组前限定数据

PHP程序员站--PHP程序员之家

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

SELECT ZIP

www phperz com

FROM Customers

PHP程序员站--PHP程序员之家

WHERE State = 'KY'

www~phperz~.com

GROUP BY ZIP PHP程序员站

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

和GROUP BY一样,WHERE不支持聚合函数。

PHP程序员站

#4:返回所有组

www.phperz.com

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

PHP程序员站

SELECT ZIP

www.phperz.com

FROM Customers

PHP程序员站

WHERE State = 'KY' PHP程序员站--PHP程序员之家

GROUP BY ALL ZIP phperz.com

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

SELECT ZIP, Count(ZIP) AS KYCustomersByZIP

PHP程序员站

FROM Customers PHP程序员站

WHERE State = 'KY'

PHP程序员站

GROUP BY ALL ZIP

www phperz com

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

远程查询不支持GROUP BY ALL。

phperz.com

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

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

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

phperz.com

SELECT ZIP, Count(ZIP) AS CustomersByZIP

PHP程序员站--PHP程序员之家

FROM Customers www~phperz~.com

GROUP BY ZIP www phperz com

HAVING Count(ZIP) = 1 phperz.com

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

www phperz com

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

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

www phperz com

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

#7:用聚合总计分组值

phperz.com

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

PHP程序员站

SELECT OrderID, Sum(Cost * Quantity) AS OrderTotal

www phperz com

FROM Orders

PHP程序员站--PHP程序员之家

GROUP BY OrderID www~phperz~.com

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

#8:总计聚合

PHP程序员站--PHP程序员之家

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

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

FROM Orders

phperz.com

GROUP BY Customer, OrderNumber PHP程序员站--PHP程序员之家

WITH ROLLUP

PHP程序员站

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

www phperz com

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

www~phperz~.com

#9:总计每一列

PHP程序员站--PHP程序员之家

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

phperz.com

SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotal PHP程序员站--PHP程序员之家

FROM Orders

www phperz com

GROUP BY Customer, OrderNumber

www phperz com

WITH CUBE

www~phperz~.com

用CUBE得到的总计最为复杂。不仅完成聚合与ROLLUP的工作,而且还求定义组的其它列的值。也就是说,CUBE总计每一个可能的列组合。 PHP程序员站--PHP程序员之家

CUBE不支持GROUP BY ALL。 PHP程序员站

#10:给总计排序

PHP程序员站--PHP程序员之家

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

SELECT GROUPING(Customer), OrderNumber, Sum(Cost * Quantity) AS OrderTotal

PHP程序员站--PHP程序员之家

FROM Orders

PHP程序员站--PHP程序员之家

GROUP BY Customer, OrderNumber www~phperz~.com

WITH CUBE

www~phperz~.com

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

PHP程序员站--PHP程序员之家

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

www phperz com


 上一篇:从4.0到5.1 为什么MySQL却被冠名"玩具数据库"   下一篇:深入浅出举例应用 SQL数据库使用系列
 
 相关文章
 
发表评论
全部评论(0条)
 
 站内搜索
 热门搜索 mysql  基础  php基础  url
高级搜索 网站地图 站长工具 IP查询 收藏本站
 热点文章
 随机推荐
网站首页 | 网站地图 | 高级搜索 | RSS订阅
PHP程序员站 Copyright © 2007,PHPERZ.COM All Rights Reserved 粤ICP备07503606号 联系站长