Oracle分析函数model使用时需要注意的几个地方(二)
2018-03-23 13:28
1451 查看
接着上文
Oracle分析函数model使用时需要注意的几个地方(一)
分析函数中的model函数功能强大,对于做数据分析的人来说绝对是一个利器。
我曾经用model函数改写了数十个用存储过程实现的报表取数,一个SQL语句就完全替代了一个上百行代码的存储过程,而且报表口径也完成了统一,这一点在我另外一篇文章中做了详细说明:
基于model函数建设口径统一的统计指标库
虽然model函数很强大,但刚接触的时候还是不免有很多需要留意的地方,一不小心就会发现统计结果与预想的不一样。这里罗列几个方面并给出解决方案:
上述语句报错的原因是字符串【‘啤酒、王老吉、饮料’】超过了PRODTYPE字段VARCHAR2(10)的长度。
实际场景中,大部分时候表结构是无法修改的,也可能是对一个查询结果进行model,更加无从修改。此时可以使用第二种办法:
这里用rpad函数虚拟了一个50个0字符的newprodtype字段,根据需要可以自定义长度。
此时dimension的维度变成了2维,因此在model中需要对2个维度都进行设置。这里解释一下这个model语句:
quantity[‘啤酒、王老吉、饮料’,’0’]=sum(quantity)[any,prodtype
in(‘啤酒’,’王老吉’,’饮料’)]
=号左边的[]内,分别表示model结果集里newprodtype=’啤酒、王老吉、饮料’和prodtype=’0’。
=号右边的[]内,表示对原表的筛选条件,any表示newprodtype取所有记录,也可以用1=1之类恒等式替代;prodtype in(‘啤酒’,’王老吉’,’饮料’)是对prodtype字段值的筛选。
此时的查询结果实际上是这样的:
经过decode转换后,得到了我们需要的结果。
Oracle分析函数model使用时需要注意的几个地方(一)
分析函数中的model函数功能强大,对于做数据分析的人来说绝对是一个利器。
我曾经用model函数改写了数十个用存储过程实现的报表取数,一个SQL语句就完全替代了一个上百行代码的存储过程,而且报表口径也完成了统一,这一点在我另外一篇文章中做了详细说明:
基于model函数建设口径统一的统计指标库
虽然model函数很强大,但刚接触的时候还是不免有很多需要留意的地方,一不小心就会发现统计结果与预想的不一样。这里罗列几个方面并给出解决方案:
3、错误ORA-25137 Data value out of range
model语句中组装的新的分类,长度不能超过原表dimension字段的长度。否则就会报ORA-25137这个错。SQL> desc t_saleamount Name Type Nullable Default Comments -------- ------------ -------- ------- -------- YEARMON DATE Y PRODTYPE VARCHAR2(10) Y QUANTITY NUMBER(10) Y AMOUNT NUMBER(12,2) Y SQL> select * from t_saleamount where yearmon=date'2018-03-01' and prodtype in('啤酒','王老吉','饮料') 2 model 3 partition by(yearmon) 4 dimension by (prodtype) 5 measures(amount,quantity) 6 (quantity['啤酒、王老吉、饮料']=sum(quantity)[prodtype in('啤酒','王老吉','饮料')] 7 ,amount['啤酒、王老吉、饮料']=sum(amount)[prodtype in('啤酒','王老吉','饮料')]); ORA-25137: Data value out of range
上述语句报错的原因是字符串【‘啤酒、王老吉、饮料’】超过了PRODTYPE字段VARCHAR2(10)的长度。
解决办法1.修改表结构,加大dimension字段的长度
SQL> alter table t_saleamount modify PRODTYPE VARCHAR2(20); Table altered SQL> select * from t_saleamount where yearmon=date'2018-03-01' and prodtype in('啤酒','王老吉','饮料') 2 model 3 partition by(yearmon) 4 dimension by (prodtype) 5 measures(amount,quantity) 6 (quantity['啤酒、王老吉、饮料']=sum(quantity)[prodtype in('啤酒','王老吉','饮料')] 7 ,amount['啤酒、王老吉、饮料']=sum(amount)[prodtype in('啤酒','王老吉','饮料')]) 8 / YEARMON PRODTYPE AMOUNT QUANTITY ----------- -------------------- ---------- ---------- 2018/3/1 饮料 43348 32 2018/3/1 啤酒 11464 3785 2018/3/1 王老吉 20524 5870 2018/3/1 啤酒、王老吉、饮料 75336 9687
实际场景中,大部分时候表结构是无法修改的,也可能是对一个查询结果进行model,更加无从修改。此时可以使用第二种办法:
解决办法2.增加虚拟字段
SQL> alter table t_saleamount modify PRODTYPE VARCHAR2(10); Table altered SQL> SQL> select decode(prodtype,'0',newprodtype,prodtype) prodtype,yearmon,amount,quantity from ( 2 select prodtype,lpad('0',50,'0') as newprodtype,yearmon,amount,quantity 3 from t_saleamount 4 where yearmon=date'2018-03-01' and prodtype in('啤酒','王老吉','饮料') 5 ) 6 model 7 partition by(yearmon) 8 dimension by (newprodtype,prodtype) 9 measures(amount,quantity) 10 (quantity['啤酒、王老吉、饮料','0']=sum(quantity)[any,prodtype in('啤酒','王老吉','饮料')] 11 ,amount['啤酒、王老吉、饮料','0']=sum(amount)[any,prodtype in('啤酒','王老吉','饮料')]); PRODTYPE YEARMON AMOUNT QUANTITY -------------------------------------------------- ----------- ---------- ---------- 饮料 2018/3/1 43348 32 啤酒 2018/3/1 11464 3785 王老吉 2018/3/1 20524 5870 啤酒、王老吉、饮料 2018/3/1 75336 9687
这里用rpad函数虚拟了一个50个0字符的newprodtype字段,根据需要可以自定义长度。
此时dimension的维度变成了2维,因此在model中需要对2个维度都进行设置。这里解释一下这个model语句:
quantity[‘啤酒、王老吉、饮料’,’0’]=sum(quantity)[any,prodtype
in(‘啤酒’,’王老吉’,’饮料’)]
=号左边的[]内,分别表示model结果集里newprodtype=’啤酒、王老吉、饮料’和prodtype=’0’。
=号右边的[]内,表示对原表的筛选条件,any表示newprodtype取所有记录,也可以用1=1之类恒等式替代;prodtype in(‘啤酒’,’王老吉’,’饮料’)是对prodtype字段值的筛选。
此时的查询结果实际上是这样的:
经过decode转换后,得到了我们需要的结果。
相关文章推荐
- Oracle分析函数model使用时需要注意的几个地方(一)
- 使用函数模板需要注意的几个地方
- Oracle 使用concat函数需要注意的地方
- PHP常量使用的几个需要注意的地方
- access中使用SQL语句需要注意的几个地方
- PHP常量使用的几个需要注意的地方(谨慎使用PHP中的常量)
- C语言(5) 函数使用需要注意的地方
- Oracle中count()函数需要注意的地方
- PHP IN_ARRAY 函数使用需要注意的地方
- access中使用SQL语句需要注意的几个地方
- php in_array 函数使用说明与in_array需要注意的地方说明
- 使用proguard需要注意的几个地方
- php in_array 函数使用说明与in_array需要注意的地方说明
- C++使用localtime函数需要注意的地方
- 说几个oracle注入需要注意的地方
- PHP IN_ARRAY 函数 使用需要注意的地方
- PHP IN_ARRAY 函数 使用需要注意的地方
- C++使用localtime函数需要注意的地方
- 写正确函数需要注意的地方:输入两个整数n和m,从数列1,2,3,...n中随意取几个数,使其和为m,列出所有可能组合
- 使用 IAR for AVR 时需要注意的几个地方