Oracle:一篇文章理解model高级语句

简介: Oracle 高级语句model的概念和基本用法,对数据仓库有了解,想要在数据库上实现数据仓库功能的可以看看

     Oracle 从10g开始支持model高级语句,使用model语句,可以在表上定义一个数据立方体,这个立方体由它的维度和度量定义,并通过规则对每个单元的值进行计算,这相当于是把关系表转换成了多维数组,这个多维不止可以是三维,可以是包含一维、二维的任意维度。这样也就提供了一种在oltp数据库里进行olap的方法。

1 model语句的基本语法

       model语句的语法在Oracle数据库里是比较复杂的,其基本语法可以从一个简单的例子看到,示例代码中用到的基表已经实现创建,只有三条数据

SQL>select*from t;      DIM1       DIM2      VALUE
---------- ---------- ----------001012103


一个简单的model语句如下面所示:

select*from t 
model
dimension by(dim1, dim2)--定义维度measures (value,0 result)---定义度量(-----定义规则  result[0,0]=-1)

     model后面由三部分组成,dimensiond定义数据立方体的维度,定义维度的列必须是基表里的列,measures定义数据立方体的度量,度量可以来自基表,也可以自己定义,最后括弧里面定义的是用于计算度量的规则集。这些规则集默认按照顺序应用的刚才定义的数据立方体上。规则集必须存在,但可以为空,下面看一下数据立方体是怎么定义的。

2 定义立方体

     model语句的执行类似于过程语言,先定义一个数据立方体,然后按照顺序在这个立方体上应用规则里定义的规则。通过一个规则集为空的例子可以简单直接地看到model语句是如何定义数据立方体的。

SQL> with t(id, value)as(select rownum, rownum from dual connect by level <=3)select*from t
        model
        dimension by(id)        measures (value,100 r1,100 r2)();          ID      VALUE         R1         R2
---------- ---------- ---------- ----------111001002210010033100100

    上面的示例中,规则集为空,定义立方体后没有应用任何规则,基表由with语句定义,是一个3行3列的表,由model定义的立方体中,使用基表中的id作为维度,value作为度量,另外又定义了两个度量r1,r2,基表中有的度量值使用基表中的值作为数据立方体相应单元的值,基表中没有的值则使用度量中指定的值(度量定义前面的数字)作为默认值。

3 规则的定义和使用

     model语句的复杂性在于它支持复杂的规则定义,为了简单直观,这里还是使用示例来说明

select*from t 
model
dimension by(dim1, dim2)measures (value, cast(nullas number) result)(  result[0,0]=-1,--位置引用  result[dim1=1, dim2=0]=-3,---符号引用  result[-1, for dim2 in(selectcount(*)from dual)]=-4,--位置引用  result[-2, dim2=1]=-10,--混合引用  result[-3, dim2=-1]=-100,--混合引用  result[-4,-1]=-1000----位置应用)orderby dim1, dim2;

     表t还是上面定义的表,这里定义了6条规则,要想理解这6条规则,首先要理解几个概念和定义。首先,对每一条规则来说,等号的左边是要操作的单元,等号的右边是对单元的赋值或者操作,等号左边需要引用要操作的单元,这里有三种引用方法,符号维度引用、位置维度引用和混合维度引用,所谓的符号维度引用,必须是一个包含维度名称的表达式,比如上面示例中的result[dim1=1, dim2=0],除了符号位置应用之外的则是位置维度引用,简单的位置维度引用比如上面例子中的result[0,0],值得注意的是,像result[-1, for dim2 in (select count(*) from dual)]这样复杂的引用也是位置维度引用,混合维度引用是在多个维度引用时,一部分维度是符号维度引用,一部分维度是位置维度引用,如上面的示例中的result[-2, dim2=1]。

      为什么要区分符号维度引用和位置维度应用,这两种引用的区别在哪里?简单来说,符号维度引用用来引用已经存在的数据,位置维度引用可以用来引用必须要加入的数据,这些数据本来不存在。至于混合维度引用,上面的规则依然使用,混合维度里符号维度必须为已存在的数据,位置维度则可以为不存在的需要加入的数据。

      这样的区分有实际意义吗?其实是有的,关键在于Oracle对立方体里的单元的处理方式。Oracle对立方体内的单元的处理方式有三种,有三个关键字update/upsert all/upsert来定义,update只更新立方体内已有的数据,upsert在更新存在的单元的同时,也创建位置维度引用的不存在的单元,upsert all和upsert不同的是,它还创建混合应用中符号维度引用已经存在的单元。默认的处理方式是upsert。说起来比较枯燥,还是使用示例来说明比较直观。先看默认的方式即upsert

select*from t 
model
dimension by(dim1, dim2)measures (value, cast(nullas number) result)(  result[0,0]=-1,--位置引用  result[dim1=1, dim2=0]=-3,---符号引用  result[-1, for dim2 in(selectcount(*)from dual)]=-4,--位置引用  result[-2, dim2=1]=-10,--混合引用  result[-3, dim2=-1]=-100,--混合引用  result[-4,-1]=-1000----位置应用)orderby dim1, dim2;DIM1       DIM2      VALUE     RESULT
---------- ---------- ---------- -----------4-1-1000---位置引用-11-4----位置引用。dim2 维度是select语句定义的001-1---数值数据集012103-3

      上面的示例中,注释已经说的比较清除了,后面三行数据引用的是原始的数据立方体里的数据,另外两行数据的单元都是位置维度引用的。混合维度引用和符号维度引用的单元在这里没有出现。下面看一下update的情况

select*from t 
           model
           dimension by(dim1, dim2)           measures (value, cast(nullas number) result)           rules update(             result[0,0]=-1,--位置引用             result[dim1=1, dim2=0]=-3,---符号引用             result[-1, for dim2 in(selectcount(*)from dual)]=-4,--位置引用             result[-2, dim2=1]=-10,--混合引用             result[-3, dim2=-1]=-100,--混合引用             result[-4,-1]=-1000----位置应用)orderby dim1, dim2;           DIM1       DIM2      VALUE     RESULT
---------- ---------- ---------- ----------001-1012103-3

只有原始数据立方体内存在的数据。最后是upsert all

select*from t 
   model
   dimension by(dim1, dim2)   measures (value, cast(nullas number) result)   rules upsert all 
(     result[0,0]=-1,--位置引用     result[dim1=1, dim2=0]=-3,---符号引用     result[-1, for dim2 in(selectcount(*)from dual)]=-4,--位置引用     result[-2, dim2=1]=-10,--混合引用     result[-3, dim2=-1]=-100,--混合引用     result[-4,-1]=-1000----位置应用)orderby dim1, dim2;           DIM1       DIM2      VALUE     RESULT
---------- ---------- ---------- -----------4-1-1000--位置引用-21-10--混合引用,符号引用的维度在初始数据集中存在-11-4--位置引用001-1--初始数据集012103-36 rows selected.

     上面出现的数据包含数据立方体原始数据,位置维度引用数据,以及一行混合维度引用数据,这行混合维度应用数据在这里出现的原因是它的符号维度应用dim2=1在原始的数据立方体内存在,尽管它的位置维度引用-2在原始数据立方体里不存在,而另一个混合维度引用单元result[-3, dim2= -1]在结果集里不存在是因为它的符号维度引用dim2= -1在原始数据立方体里不存在。从上面的例子里可以看出,使用符号维度引用原始立方体里不存在的维度值是没有意义的,做的计算也只是无用功。

相关文章
|
4月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
94 0
|
6月前
Oracle-高级子查询
Oracle-高级子查询
26 0
|
12月前
|
SQL XML Oracle
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(下)
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(下)
|
12月前
|
SQL XML Oracle
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(中)
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(中)
|
12月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(上)
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作(上)
|
Oracle 关系型数据库
oracle学习60-oracle之高级子查询2
oracle学习60-oracle之高级子查询2
73 0
oracle学习60-oracle之高级子查询2
|
Oracle 关系型数据库
oracle学习61-oracle之高级子查询1
oracle学习61-oracle之高级子查询1
63 0
oracle学习61-oracle之高级子查询1
|
Oracle 关系型数据库
oracle学习59-oracle之高级子查询之课后练习
oracle学习59-oracle之高级子查询之课后练习
49 0
oracle学习59-oracle之高级子查询之课后练习