Oracle Model子句

Model子句的使用
   Model子句是Oracle1g中新增的一个性特性,model子句提供了诸如电子表格计算之类的计算能力。即像访问数据元素那样访问表格中某行的某个列

首先展示一个简单Model示例的介绍
--create table
create table t_product_sale_detail
(
  pid          number(12,0),
  year         number(5,0),
  month        number(2,0),
  sales_amount number(12,2)
);

--init data
insert into t_product_sale_detail values(1,2010,1,10000);
insert into t_product_sale_detail values(1,2010,2,10010);
insert into t_product_sale_detail values(1,2010,3,10020);
insert into t_product_sale_detail values(1,2010,4,10030);
insert into t_product_sale_detail values(1,2010,5,10400);
insert into t_product_sale_detail values(1,2010,6,10500);
insert into t_product_sale_detail values(1,2010,7,10600);
insert into t_product_sale_detail values(1,2010,8,10700);
insert into t_product_sale_detail values(1,2010,9,10800);
insert into t_product_sale_detail values(1,2010,10,10900);
insert into t_product_sale_detail values(1,2010,11,11000);
insert into t_product_sale_detail values(1,2010,12,12000);

insert into t_product_sale_detail values(2,2011,1,10000);
insert into t_product_sale_detail values(2,2011,2,10010);
insert into t_product_sale_detail values(2,2011,3,10020);
insert into t_product_sale_detail values(2,2011,4,10030);
insert into t_product_sale_detail values(2,2011,5,10400);
insert into t_product_sale_detail values(2,2011,6,10500);
insert into t_product_sale_detail values(2,2011,7,10600);
insert into t_product_sale_detail values(2,2011,8,10700);
insert into t_product_sale_detail values(2,2011,9,10800);
insert into t_product_sale_detail values(2,2011,10,10900);
insert into t_product_sale_detail values(2,2011,11,11000);
insert into t_product_sale_detail values(2,2011,12,12000);


eg1:根据2011年的销售记录,预测2012年1,2,3月的销售量
select pid,year,month,sales_amount from t_product_sale_detail
model
partition by (pid)
dimension by(year,month)
measures(sales_amount)
(
sales_amount[2012,1] = sales_amount[2011,1],
--sales_amount[year=2012,month=1]采用符号标记
    sales_amount[2012,2] = sales_amount[2011,2] + sales_amount[2011,1],
    sales_amount[2012,3] = sales_amount[2011,3] * 1.5
)
order by pid,year,month;

我们分析上面的语句
1. partition by (pid)值根据pid进行分区,跟分析函数的partition一样,可以根据分区并行的处理数据
2. dimension by(year,month) 定义数组维数是year和month,即根据根据每行的year和month值访问一行,相当于year,month是数组的索引。必须唯一定位到一行
3. measures(sales_amount)用来指定需要进行计算的列
4. measures之后的括号之内用于指定列的计算规则


eg2:我们这里还有一个需求,预测2012年一月分的销售量为2011年一季度的平均值,2012年二月份的销售量为2011年第二季度的平均值,2012年3月份的销售量为2011年第三季度的平均值

select pid,year,month,sales_amount from t_product_sale_detail
model
partition by (pid)
dimension by(year,month)
measures(sales_amount)
(
    sales_amount[2012,1] = avg(sales_amount)[2011,month between 1 and 3],
    sales_amount[2012,2] = avg(sales_amount)[2011,month between 4 and 6],
sales_amount[2012,3] = avg(sales_amount)[2011,month between 7 and 8]
)
order by pid,year,month;

注:我们发现model子句中我们可以使用between and来指定范围内的数据单元,并且返回内的数据单元进行分析和统计


eg3:将2012年一月份的的销量设置为所有年份和月份的销量总和
select pid,year,month,sales_amount from t_product_sale_detail
model
partition by (pid)
dimension by(year,month)
measures(sales_amount)
(
    sales_amount[2012,1] = sum(sales_amount)[month is any,any]
)
order by pid,year,month;

注:我们可以通过any关键字访问所有的数据单元,并且将这些数据进行分析和统计

eg4:我们需要预测2012年产品每月份的销量统计,并且2012年的销量需要增长25%

select pid,year,month,sales_amount from t_product_sale_detail
model
partition by (pid)
dimension by(year,month)
measures(sales_amount)
(
    sales_amount[2012,for month from 1 to 12 increment 1] = sales_amount[2011,currentv()] * 1.25
)
order by pid,year,month;

注:我们可以发现上面使用了for from to increment关键字和currentv()函数,通过上面例子我们可以清楚的发现,currentv()获取的当前的维度值,然后采用for循环访问数据单元


Model子句中空值(model子句之前,不存在的维度记录)处理
1.model两种处理空值的模式
  a.IGNORE NAV
忽略空值,数字返回0,字符串返回空串,日子返回一个默认的日期
  b.KEEP NAV
即保留空值,model子句默认是保留空值

--测试语句
select pid,year,month,sales_amount from t_product_sale_detail
model ignore nav
partition by (pid)
dimension by(year,month)
measures(sales_amount)
(
    sales_amount[2013,for month from 1 to 12 increment 1] = sales_amount[2012,currentv()] * 1.25
)
order by pid,year,month;

2.我们可以通过空值处理函数处理空值
  Model子句中的控制判断使用”is present” ,如果指定cell存在,返回true,
所以我们可以通过case语句进行空值处理
  我们还可以使用presentnv()和presentv()空值函数处理
  presentv(cell,exp1,exp2)如果cell不为空,则返回exp1,否则返回exp2
  presentnv(cell,exp1,exp2)如果cell为空,则返回exp1,否则返回exp2



跟新已有的单元
Model子句有两种跟新单元的模式
1.model子句默认的更新模式为,如果表达式左端的引用单元不存在,则更新该单元,如果该单元不存在,就在数组中创建一条新的记录
2.可以通过(rules update)来切换model子句的更新模式,即左端的引用单元不存在时,则不创建新纪录

eg:
select pid,year,month,sales_amount from t_product_sale_detail
model
partition by (pid)
dimension by(year,month)
measures(sales_amount)
rules update
(
    sales_amount[2012,for month from 1 to 12 increment 1] = sales_amount[2011,currentv()] * 1.25
)
order by pid,year,month;

猜你喜欢

转载自xiongxu.iteye.com/blog/1832160