诉求:查询Oracle数据库N个表,将查询结果的一列转化为一条数据,需要函数WM_CONCAT:

SELECT REPLACE(WM_CONCAT(E.CARD), ',', '|') FROM BB_USER_T E;

网上找了一下,若还有更多诉求,Oracle函数不能实现:

Oracle提供了很多预定义好的聚集函数,下文基本上是对Orace文档(http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14289/dciaggfns.htm#sthref542) 的翻译。

Oracle提供了很多预定义好的聚集函数,比如Max(), Sum(), AVG(), 但是这些预定义的聚集函数基本上都是适应于标量数据(scalar data), 对于复杂的数据类型,比如说用户自定义的Object type, Clob等, 是不支持的。

但是,幸运的是, 用户可以通过实现Oracle的Extensibility Framework中的ODCIAggregate interface来创建自定义聚集函数,而且自定义的聚集函数跟内建的聚集函数用法上没有差别。

ODCI是Oracle Data Cartridge Interface 几个单词的首字母缩写, 关于Oracle Data Cartridge,可以参见这里。

1. Overview of User-Defined Aggregate Functions

通过实现ODCIAggregate rountines来创建自定义的聚集函数。可以通过定义一个对象类型(Object Type),然后在这个类型内部实现ODCIAggregate 接口函数(routines), 可以用任何一种Oracle支持的语言来实现这些接口函数,比如C/C++, JAVA, PL/SQL等。在这个Object Type定义之后,相应的接口函数也都在该Object Type Body内部实现之后, 就可以通过CREATE FUNCTION语句来创建自定义的聚集函数了。

每个自定义的聚集函数需要实现4个ODCIAggregate 接口函数, 这些函数定义了任何一个聚集函数内部需要实现的操作,这些函数分别是 initialization, iteration, merging 和 termination。

(1) ODCIAggregateInitialize 这个函数用来执行初始化操作(initialization). Oracle会调用这个函数来初始化自定义函数计算。 初始化的聚集环境(aggregation context)会以对象实例(object type instance)传回给oracle.

(2) ODCIAggregateIterate 这个函数用来遍历需要处理的数据,被oracle重复调用。每次调用的时候,当前的aggreation context 和 新的(一组)值会作为传入参数。 这个函数会处理这些传入值,然后返回更新后的aggregation context. 这个函数对每一个NON-NULL的值都会被执行一次。NULL值不会被传递个聚集函数。

(3) ODCIAggregateMerge 这个函数用来把两个aggregation context整合在一起,一般用来并行计算中(当一个函数被设置成enable parallel 处理的时候)。

(4) ODCIAggregateTerminate 这个函数是Oracle调用的最后一个函数。它接收aggregation context作为参数,返回最后的aggregate value.

Example: 自定义聚集函数是如何工作的

SELECT AVG(T.Sales)FROM AnnualSales TGROUP BY T.State;

为了完成求平均值的计算,AVG函数经历下面几个步骤:

(1)  Initializes: 初始化Aggregation Context:

runningSum = 0;  runningCount = 0;

(2) Iteratively 处理每个连续的输入,同时更新aggregation context:

runningSum += inputval;  runningCount ++;

(3) 【这步是可选的】Merge 整合两个aggregation context 返回一个aggregation context. 如果需要这一步的话,它是在termination之前执行。

runningSum   =  runningSum1 + runningSum2;

runningCount  = runningCount1 + runningCount2;

(4)  Terminates 计算出最后的结果, 通过最后的aggregation context来返回最后的aggregated value.

return (runningSum / runningCount);

如果AVG是自定义的聚集函数的话,与之相对应的对象类型(object type)需要实现对应的ODCIAggregate的接口函数。变量runningSum 和 runningCount 是对象类型中的属性(attribute).

2. Creating a User-Defined Aggregate

创建一个自定义聚集函数分成两步: 如下面两个例子所示:

Example: 如何实现ODCIAggregate接口:

CREATE TYPE SpatialUnionRoutines(   STATIC FUNCTION ODCIAggregateInitialize( ... ) ...,   MEMBER FUNCTION ODCIAggregateIterate(...) ... ,   MEMBER FUNCTION ODCIAggregateMerge(...) ...,   MEMBER FUNCTION ODCIAggregateTerminate(...)); CREATE TYPE BODY SpatialUnionRoutines IS ...END;

Example:如何定义自定义聚集函数:

CREATE FUNCTION SpatialUnion(x Geometry) RETURN Geometry AGGREGATE USING SpatialUnionRoutines;

注意在定义函数的时候需要通过Aggregate Using语句来关联上对应的实现了ODCIAggregate接口的Object Type。

3. Using a User-Defined Aggregate

自定义的聚集函数可以像内置的聚集函数一样使用, 可以用在SELECT, ORDER BY, HAVING语句中。下面几个例子说明如何使用上面定义的自定义函数SpatialUnion

Example: 用在Select语句中

SELECT SpatialUnion(geometry)FROM countiesGROUP BY state

Example: 用在Having语句中,

SELECT groupcol, MyUDAG(col)FROM tabGROUP BY groupcolHAVING MyUDAG(col) > 100ORDER BY MyUDAG(col);

Example: 其他

SELECT ..., MyUDAG(col)FROM tabGROUP BY ROLLUP(gcol1, gcol2)

自定义聚集函数可以跟All, Distinct一起使用, 亦可以用在Group by的扩展语句中,像ROLLUP, CUBE, grouping sets.

4. Evaluating User-Defined Aggregates in Parallel

跟内置的聚集函数一样,自定义的聚集函数也可以并行来处理,

需要注意的是, 自定义的聚集函数需要声明为parallel-enabled, 如下

CREATE FUNCTION MyUDAG(...) RETURN ...PARALLEL_ENABLE AGGREGATE USING MyAggrRoutines;

5. User-Defined Aggregates and Analytic Functions

自定义的聚集函数可以被当做Analytic函数来用,

SELECT Account_number, Trans_date, Trans_amount,   MyAVG (Trans_amount) OVER      PARTITION BY Account_number ORDER BY Trans_date      RANGE INTERVAL '7' DAY PRECEDING) AS mavg_7dayFROM Ledger;

6.  Reusing the Aggregation Context for Analytic Functions

当一个自定义的聚集函数被用来做Analytic Function的时候,对每条记录对应的window都会计算一次aggregate。 一般的说来,每个连续的窗口包含大部分相同的数据集合。

可以通过实现ODCIAggregateDelete接口函数来让Oracle更有效地复用aggregation context.

7. An complete example for Creating and Using a User-Defined Aggregate Function

SecondMax()返回一组数里面第二大的那个值。

(1) 实现类型SecondMaxImpl,该类型包含了ODCIAggregate接口函数,

create type SecondMaxImpl as object(  max NUMBER, -- highest value seen so far   secmax NUMBER, -- second highest value seen so far  static function ODCIAggregateInitialize(sctx IN OUT SecondMaxImpl)     return number,  member function ODCIAggregateIterate(self IN OUT SecondMaxImpl,     value IN number) return number,  member function ODCIAggregateTerminate(self IN SecondMaxImpl,     returnValue OUT number, flags IN number) return number,  member function ODCIAggregateMerge(self IN OUT SecondMaxImpl,     ctx2 IN SecondMaxImpl) return number);/

(2).  实现类型SecondMaxImpl的body,

create or replace type body SecondMaxImpl is static function ODCIAggregateInitialize(sctx IN OUT SecondMaxImpl) return number is begin  sctx := SecondMaxImpl(0, 0);  return ODCIConst.Success;end; member function ODCIAggregateIterate(self IN OUT SecondMaxImpl, value IN number) return number isbegin  if value > self.max then    self.secmax := self.max;    self.max := value;  elsif value > self.secmax then    self.secmax := value;  end if;  return ODCIConst.Success;end; member function ODCIAggregateTerminate(self IN SecondMaxImpl,     returnValue OUT number, flags IN number) return number isbegin  returnValue := self.secmax;  return ODCIConst.Success;end; member function ODCIAggregateMerge(self IN OUT SecondMaxImpl, ctx2 IN SecondMaxImpl) return number isbegin  if ctx2.max > self.max then    if ctx2.secmax > self.secmax then       self.secmax := ctx2.secmax;    else      self.secmax := self.max;    end if;    self.max := ctx2.max;  elsif ctx2.max > self.secmax then    self.secmax := ctx2.max;  end if;  return ODCIConst.Success;end;end;/

(3). 创建自定义聚集函数SecondMax()

CREATE FUNCTION SecondMax (input NUMBER) RETURN NUMBER PARALLEL_ENABLE AGGREGATE USING SecondMaxImpl;

(4). 使用自定义聚集函数SecondMax()

SELECT SecondMax(salary), department_idFROM employeesGROUP BY department_idHAVING SecondMax(salary) > 9000;

oracle合并列的函数wm_concat相关推荐

  1. html合并列的函数,mergecells

    mergeCells里面有什么参数分别是什么意思 mergeCells(a,b,c,d) 单元格合并函数 a 单元格的列号 b 单元格的行号 c 从单元格[a,b]起,向下合并到c列 d 从单元格[a ...

  2. mysql unpivot_SQL(横表和纵表)行列转换,PIVOT与UNPIVOT的区别和使用方法举例,合并列的例子...

    使用过SQL Server 2000的人都知道,要想实现行列转换,必须综合利用聚合函数和动态SQL,具体实现起来需要一定的技巧,而在SQL Server 2005中,使用新引进的关键字PIVOT/UN ...

  3. oracle 查询列合并行,Oracle 查询合并列

    在ORACLE  查询时,有时要将多个列合并成一行,其方法如下: 1. decode 函数 decode 函数的语法为: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省 ...

  4. Oracle列合并成行之wm_concat函数浅析

    文章目录 1.LOB类型 2. wm_concat()函数的使用 在工作中提取数据报表时碰到了很多只有一个字段不同,其他N个字段都相同的数据,用行来显示不免觉得太过冗余,于是搜寻网络发现Oracle有 ...

  5. oracle wm_concat 替换函数,wm_concat 函数在PG中替代

    WM_CONCAT 经常使用到行转列上,早期的代码里这个函数用的会比较多,但是可惜在12c中,这个函数已经过期了: 所以,在后续的开发中,不要再使用这个函数.在MOS中,Oracle也不建议客户使用这 ...

  6. oracle开窗函数是什么,ORACLE数据库(六)-----开窗函数

    ORACLE数据库(六)-----开窗函数 开窗函数又名分析函数.窗口函数.OLAP(数据分析)函数 聚合函数:将数据按照一定的规则分组,统一分析各组的某项情况,每个分组返回一行结果 开窗函数:将数据 ...

  7. Oracle提供的序号函数

    Oracle提供的序号函数: 以emp表为例: 1: rownum 最简单的序号 但是在order by之前就确定值. select rownum,t.* from emp t order by en ...

  8. SQL 合并列值和拆分列值

     合并列值表结构,数据如下: view plain id value ----- ------ 1 aa 1 bb 2 aaa 2 bbb 2 ccc 需要得到结果: id values ------ ...

  9. Impala中行转列在合并列

    Impala中行转列在合并列 Impala中如何实现将多列转为一行,其实Impala中自带函数可以实现,不用自定义函数. 下面我开始演示: -bash-4.1$ impala-shell Starti ...

  10. Oracle中的wn_concat()函数

    最近实习写SQL语句用到了这个函数来进行子查询合并查询,了解了之后特来记录一下 wm_concat()函数 wm_concat()函数是oracle独有的,他和Mysql中的group_concat( ...

最新文章

  1. Naive Operations (线段树 分析复杂度)
  2. 再见!人人影视...
  3. python在中小学教学中的应用-小学信息技术教学中进行Python 编程语言教学的策略...
  4. VMware 下扩展linux硬盘空间
  5. mysql maria引擎_MySQL体系结构和存储引擎概述
  6. python获取当前时间代码_python当前时间格式化代码
  7. 功能、资源权限管理的设计
  8. 前端学习(623):交换两个变量的值
  9. Hibernate一对多映射示例注释
  10. Django: OperationalError / no such table
  11. 上传jar包到私服(仅限于翼支付公司工作流程使用)和涉及的技术总结
  12. js系列教程13-原型、原型链、作用链、闭包全解
  13. python:只想在opencv中显示红色通道?
  14. Android重拾设计模式系列——简单工厂模式
  15. 人生成功的十大说话技巧
  16. php框架laravel下载,Laravel框架下载,安装及路由操作图文详解
  17. 计算机故障排除原则和方法
  18. Excel在统计分析中的应用—第十章—方差分析-方差分析表
  19. 处理器最新排行_CPU跑分工具CINBENCH R23排行榜出炉:AMD锐龙单核、多核均屠榜
  20. 软件测试面试题:常见的性能测试方法有哪些?以及每类测试方法的目的是什么?

热门文章

  1. 3步接入顺丰快递云打印电子面单接口API
  2. Freemarker word导出教程
  3. el-select 默认选中url参数对应的选项
  4. Android 小知识:使用shell screencap / screenshot命令截屏
  5. edgewin10无法安装_win10内置Edge浏览器遇到“您未安装FLASH控件”如何解决
  6. 详解Java的交互式编程环境:jshell
  7. 警方抓获百度网盘“破解版”Pandownload开发者
  8. ps景观平面图转鸟瞰图_小清新ps做景观鸟瞰图
  9. CCNA考试题库中英文翻译版及答案17
  10. 麦克纳姆轮全向移动原理(运动速度方向分析)