很久之前就想写出来,就是因为自己太懒,憋了怎么久。本文关于使用ORACLE分析函数对一些经济指标进行计算。表indi_value有3个关键的字段:indi_date,indi_value,indi_id分别对应 指标日期,指标值,指标ID。这个表中保存了很多种类的经济指标,如CPI,RPI,GDP,这些指标通过 指标ID来标识。下面是针对CPI做的处理,公式如下:

公式说明:将2010年1月份当作基期。分别计算基期前后的定基价格指数。直接看代码

  1. with base as ( select indi_date,indi_value
  2. from indi_value
  3. -- 获取20060101 - 20131101区间内要计算的数据
  4. where indi_id='C0A0102' and indi_date between '20060101' and '20131101'
  5. ),
  6. ---获取大于基期的数据,数据按日期升序,并且使基期=100,往后的值都为空,然后通过行间计算,进行填补
  7. up as (select indi_date,indi_value,
  8. case when indi_date like '201001%'
  9. then 100 else null end as v,rank() OVER(order by indi_date) as d
  10. from base
  11. where indi_date between '20100101' and '20131101'),
  12. upx as (select d,v
  13. from up model
  14. dimension by (d)
  15. measures (indi_value,v)
  16. RULES UPDATE
  17. (
  18. V[d>1]=v[cv(d)-1]*(1+(indi_value[cv(d)]-100)/100) --大于基期的计算公式
  19. )
  20. ),
  21. --获取小于基期的数据,结尾日期要能够将基期数据包含到要计算的数据中,数据按日期倒序,
  22. --并且使基期=100,往后的值都为空,然后通过行间计算,进行填补
  23. down as (select indi_date,indi_value,
  24. case when indi_date like '201001%'
  25. then 100 else null end as v,rank() OVER(order by indi_date desc) as d
  26. from base
  27. where indi_date between '20060101' and '20100201'),
  28. downx as (select d,v
  29. from down model
  30. dimension by (d)
  31. measures (indi_value,v)
  32. RULES UPDATE
  33. (
  34. V[d>1]=v[cv(d)-1]/(1+(indi_value[cv(d)-1]-100)/100) --小于基期的计算公式
  35. )
  36. )
  37. select u.indi_date,null as v,null as r,x.v as b
  38. from upx x join up u on x.d=u.d
  39. union
  40. select d.indi_date,null as v,null as r, x.v as b
  41. from downx x join down d on x.d=d.d

以上语句的结果即为对CPI的定基价格指数计算结果。其中 C0A0102是 CPI在表中的指标ID。语句基本上分位4部分

第一部分:主要是获取要计算的时间区间内的所有数据,并放到一个名叫base的临时表中。

  1. with base as ( select indi_date,indi_value
  2. from indi_value
  3. -- 获取20060101 - 20131101区间内要计算的数据
  4. where indi_id='C0A0102' and indi_date between '20060101' and '20131101'
  5. ),

第二部分:计算大于基期的那部分数据

  1. ---获取大于基期的数据,数据按日期升序,并且使基期=100,往后的值都为空,然后通过行间计算,进行填补
  2. up as (select indi_date,indi_value,
  3. case when indi_date like '201001%'
  4. then 100 else null end as v,rank() OVER(order by indi_date) as d
  5. from base
  6. where indi_date between '20100101' and '20131101'),
  7. upx as (select d,v
  8. from up model
  9. dimension by (d)
  10. measures (indi_value,v)
  11. RULES UPDATE
  12. (
  13. V[d>1]=v[cv(d)-1]*(1+(indi_value[cv(d)]-100)/100) --大于基期的计算公式
  14. )
  15. )

第三部分:计算小于基期的那部分数据,原理同第二部分。

第四部分:将第二,第三部分的计算结果整合起来

  1. select u.indi_date,null as v,null as r,x.v as b
  2. from upx x join up u on x.d=u.d
  3. union
  4. select d.indi_date,null as v,null as r, x.v as b
  5. from downx x join down d on x.d=d.d

其中第二,第三部分又可以分为2个步骤。

(1)是还是获取要计算的数据,并添加一列作为计算结果,且基期对应的值为100。添加一列排序号作为(2)步的取值下标。

(2)使用oracle提供的行间计算函数 model 来根据(1)中的indi_value,和 第一行的基期结果100来计算第二行的定基价格指数。

这样就会一行一行的计算下去,后一行的结果总是基于前一行的值来计算。(1)中的列 d 可以起类似于数组的作用。

measures 后面的 rules update是可以去掉的。

SQL描述(2)的更多相关文章

  1. 用SQL描述树

    /*40条(1层) SELECT COUNT(*) FROM t01_mwfl WHERE AZFSDM=01 AND LEVEL=1 START WITH PID=0 CONNECT BY PRIO ...

  2. SQL Server-分页方式、ISNULL与COALESCE性能分析(八)

    前言 上一节我们讲解了数据类型以及字符串中几个需要注意的地方,这节我们继续讲讲字符串行数同时也讲其他内容和穿插的内容,简短的内容,深入的讲解,Always to review the basics. ...

  3. 如何写复杂的SQL

    经常有人问我那非常复杂的sql是怎么写出来的,我一直不知道该怎么回答.         因为虽然我写这样的sql很顺手,可是我却不知道怎么告诉别人怎么写. 很多人将这个问题归结为天赋,我却不这么看,我 ...

  4. MyBatis基础入门《十七》动态SQL

    MyBatis基础入门<十七>动态SQL 描述: >> 完成多条件查询等逻辑实现 >> 用于实现动态SQL的元素主要有: > if > trim > ...

  5. Flink table&Sql中使用Calcite

    Apache Calcite是什么东东 Apache Calcite面向Hadoop新的sql引擎,它提供了标准的SQL语言.多种查询优化和连接各种数据源的能力.除此之外,Calcite还提供了OLA ...

  6. flyway实现java 自动升级SQL脚本

    flyway实现java 自动升级SQL脚本 为什么要用Flyway 在日常开发中,我们经常会遇到下面的问题: 自己写的SQL忘了在所有环境执行: 别人写的SQL我们不能确定是否都在所有环境执行过了: ...

  7. 20145205 《Java程序设计》第9周学习总结

    教材学习内容总结 第十六章 JDBC简介 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC目的:让Java程序设计人员在撰写数据库操作程序时可以有个统一的接口,无须依赖特 ...

  8. 开源GIS软件初探

    谈到GIS软件,首先让我们想到的便是GIS界的龙头大哥ESRI公司旗下的ArcGIS产品,从最初接触的version 9.2到如今的version 10.1,其发展可谓风生水起.MapInfo软件也不 ...

  9. hiberante入门

    Hibernate 目前企业级应用一般均采用面向对象的开发方法,而内存中的对象数据不能永久存在,如想借用关系数据库来永久保存这些数据的话,无疑就存在一个对象-关系的映射过程.在这种情形下,诞生了许多解 ...

随机推荐

  1. CentOS之NTP服务器配置

    本文使用CentOS 6.5作为搭建环境 一.服务器端配置 1.安装所需软件包 yum -y install ntp ntpdate---------------------------------- ...

  2. create index 与 alter table add index 区别

    众所周知,MySQL创建索引有两种语法,即:ALTER TABLE HeadOfState ADD INDEX (LastName, FirstName);CREATE INDEX index_nam ...

  3. eclipse 的安装和汉化

    第一步:直接百度搜索eclipse,第一个就是官方网站 第二步:点击DOWNLOAD 64BIT进入下载页面 第三步:点击DOWNLOAD进行下载 If the download doesn't st ...

  4. java 输出helloword

    1,安装jdk;2,配置环境变量;3,新建D:/Test.java文件;4,文件内容如下:public class Test{ public static void main(String[] arg ...

  5. [转]Spring 之 Log4j 的配置

  6. yaml语言教程

    大家直接去看阮一峰的教程. http://www.ruanyifeng.com/blog/2016/07/yaml.html?f=tt 简介 基本语法规则: 大小写敏感 使用缩进表示层级关系 缩进时不 ...

  7. Oracle DSI系列 01 DSI初识BBED

    DSI是Data Server Internals的缩写,是Oracle公司内部用来培训Oracle售后工程师使用的教材. 1 bbed工具使用BBED工具介绍BBED stands for Bloc ...

  8. 转载 关于restTemplate 内部实现

    2016-12-28 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6228198.html  本篇概要 RestTemplate 类图 po ...

  9. 关于mysql 间隙锁

    前段时间系统老是出现update死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...

  10. 错误:HttpServlet was not found on the Java

    我们在用Eclipse进行Java web开发时,可能会出现这样的错误:The superclass javax.servlet.http.HttpServlet was not found on t ...