利用Group by 和Having来实现分组统计(一)


客户需求分析:

  笔者最近接到一家客户的一个需求。他们部署了一个ERP系统,现在采用的就是Oracle数据库。现在由于企业统计分析的需要,要实现如下的需求。

  1、按月份来统计2009年第一季度每个供应商的采购金额。也就是说,在报表中要能够显示出2009年1月份、2月份、3月份供应商的采购金额合计,不需要明细。

  2、显示的结果按年度、月份、供应商名字进行排序。

  综合客户的要求,也就是说要实现如上这张报表。

  PL/SQL语句解析:

   select extract(YEAR FROM t.dateordered) AS 年度,extract(MONTH FROM t.dateordered) as 月份,

  p.name as 供应商名字,sum(t.linenetamt) 合计

  from c_orderline2 t

  left join c_bpartner p on p.c_bpartner_id=t.c_bpartner_id

  group by extract(YEAR FROM t.dateordered),extract(MONTH FROM t.dateordered),p.name

  having extract(YEAR FROM t.dateordered)=2009 and extract(MONTH FROM t.dateordered) in (1,2,3)

  order by p.name;

  通过以上语句就可以实现企业如上的需求。在这个需求中,笔者主要用过Group By语句与Having语句来实现。这两个是Oralce数据库中PL/SQL语言中两个很重要的分组语句。利用这个两个语句可以实现一些复杂的统计功能。对于Group By与Having语句的一些基本用法,笔者在这里不做过多描述。笔者这里想说的是,在使用这两个语句进行数据统计时需要注意的地方。在Oracle数据库系统中,对于这两个统计子句做了比较严格的使用限制。数据库管理员必须对这些使用闲置铭记在心,否则的话很容易在统计的过程中遇到错误。具体来说,有如下几个使用限制。

  1、如果选择列表中包含有列、表达式或者分组函数,那么这些列或者表达式必须出现在Group By子句中,否则数据库会提示相关的错误信息。分组函数不用出现在Group By子句中。如上面这个例子,由于在数据库基础表中存储的是下订单的日期,如2009年4月15日。也就是说,年月日是存储在同一个字段中的。但是在统计的时候,需要统计2009年1月、2月、3月的供应商采购金额。为此此时笔者先利用Extract函数从一个日期数据中抽取具体的年、月信息。这个是Oracle数据库中一个很有用的日期函数。要是没有这个函数的话,笔者还需要通过字符串等处理函数来截取年月等信息。由于Extract是一个带函数的表达式,为此其必须出现在Group By子句中。而且注意,笔者此时采用的是表达式本身,而不是其别名。也就是说,笔者没有采用group by年度,月份等表达方法。也就是说,在Group By子句中,必须采用表达式的全称,而不能够采用其别名。否则的话,数据库系统不会接受这个语句。数据库系统之所有要进行类似的控制,其背后藏有比较深层次的原因。不过作为普通数据库管理员来说,不怎么用了解数据库设计背后的内容。只需要把这个规则记在心中即可。这个规则对于大部分数据库管理员来说,可能会经常触犯他。为此笔者再次强调一遍,选择列表中如果包含有列、表达式时,这个列、表达式必须包含在Group By子句中。另外,如果采用了表达式的话,则数据库管理员即使在选择列表中采用了别名,但是在Group By子句中仍然必须采用表达式的完整表达方式,而不能够采用别名。


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3