Oracle 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子句中。而且注意,笔者此时采用的是表达式本身,而不
相关文档:
一、 常用日期数据格式
1.Y或YY或YYY 年的最后一位,两位或三位
SQL> Select to_char(sysdate,'Y') from dual;
TO_CHAR(SYSDATE,'Y')
--------------------
7
SQL> Select to_char(sysdate,'YY') from dual;
TO_CHAR(SYSDATE,'YY')
---------------------
07
SQL> Select to_char(sysdate,'YYY') from ......
TO_DATE格式(以时间:2007-11-02 13:45:25为例)
Year:
yy two digits 两位年 ......
INTERVAL YEAR TO MONTH数据类型
Oracle语法:
INTERVAL 'integer [- integer]' {YEAR | MONTH} [(precision)][TO {YEAR | MONTH}]
该数据类型常用来表示一段时间差, 注意时间差只精确到年和月. precision为年或月的精确域, 有效范围是0到9, 默认值为2.
eg:
INTERVAL '123-2' YEAR(3) TO MONTH & ......
-- 删除重复记录
DELETE from mytable t1 WHERE ROWID > (SELECT MIN (ROWID) from mytable t2 WHERE t1. key = t2.key);
-- 当前日期
SELECT TO_CHAR(SYSDATE, 'yyyy-MM-dd') from DUAL;
-- 上月当前日期
SELECT TO_CHAR(ADD_MONTHS(SYSDATE,
-1), 'yyyy-MM-dd') from DUAL;
-- 下月当前日期
SELECT
TO_C ......