Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 冲浪宝典 > 网络资源 > 数据库中如何分类、分组并总计SQL数据
【标  题】:数据库中如何分类、分组并总计SQL数据
【关键字】:SQL
【来  源】:http://blog.csdn.net/xuzhengfeng/archive/2007/04/18/1569214.aspx

数据库中如何分类、分组并总计SQL数据

Your Ad Here  

 

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

1、分类排序

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

2、减少组中的相似数据

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

SELECT ZIPFROM CustomersGROUP BY ZIP

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

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

3、分组前限定数据

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

SELECT ZIPFROM CustomersWHERE State = 'KY'GROUP BY ZIP

在GROUP BY子句求数据的值之前,WHERE对数据进行过滤,记住这一点很重要。和GROUP BY一样,WHERE不支持聚合函数。

4、返回所有组

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

SELECT ZIPFROM CustomersWHERE State = 'KY'GROUP BY ALL ZIP

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

SELECT ZIP, Count(ZIP) AS KYCustomersByZIPFROM CustomersWHERE State = 'KY'GROUP BY ALL ZIP

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

5、分组后限定数据

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

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

SELECT ZIP, Count(ZIP) AS CustomersByZIPFROM CustomersGROUP BY ZIPHAVING Count(ZIP) = 1

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

6、详细了解WHERE和HAVING

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

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

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

7、用聚合总计分组值

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

SELECT OrderID, Sum(Cost * Quantity) AS OrderTotalFROM OrdersGROUP BY OrderID

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

8、总计聚合

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

SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotalFROM OrdersGROUP BY Customer, OrderNumberWITH ROLLUP

一个包含20和25这两个OrderTotal值的组的ROLLUP行将显示OrderTotal值45。ROLLUP结果的第一个值是唯一的,因为它求所有组记录的值。那个值是整个记录集的总和。ROLLUP不支持聚合函数中的DISTINCT或GROUP BY ALL子句。

9、总计每一列

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

SELECT Customer, OrderNumber, Sum(Cost * Quantity) AS OrderTotalFROM OrdersGROUP BY Customer, OrderNumberWITH CUBE

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

10、给总计排序

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

SELECT GROUPING(Customer), OrderNumber, Sum(Cost * Quantity) AS OrderTotalFROM OrdersGROUP BY Customer, OrderNumberWITH CUBE

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

值1表明左边的值是一个总计值——ROLLUP或CUBE的运算符的结果。

值0表明左边的值是一个原始GROUP BY子句产生的详细记录。

 

mysql中操作IP地址的函数:【上一篇】
SQL 常用语法:【下一篇】
【相关文章】
  • mysql中操作IP地址的函数
  • Mysql分区?
  • PL/SQL中的 for Update of 应用一例
  • 执行SQL语句报ORA-00600 错误的解决
  • SQL基础:常用SQL语句详解
  • [Python]在cygwin下编译MySQLdb for python
  • Mysql的JDBC 的常见连接属性
  • 网站开发经验总结1--Tomcat与Mysql连接
  • 为你的MySQL数据库加铸23道安全门
  • Mysql常用数学函数
  • 【随机文章】
  • FreeBSD基本操作
  • 利用处理程序错误攻击(下)
  • ESFramework介绍之(31)―― 消息分类及对应的处理器
  • NOTE: 4 日期:2006-8-8
  • Spring2.0中新的Bean类型实现原理
  • 微软公布“.NET”第二阶段研发方向
  • Windows分区转换为Debian分区
  • vmtune 之调优字分页空间的阈值
  • o'reily ip routing memo part02
  • [技术讨论]结对编程与交换编程的对话
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.