wm_concat函数的排序问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wm_concat函数的排序问题相关的知识,希望对你有一定的参考价值。

参考技术A ODPS的wm_concat函数在行转列的时候非常有用,但在行转列的过程中的排序问题常常难以控制。官网的order子句在3.6.2版本中用不了,所以简单写了个SQL来实现:

①创建测试表及数据

create table tianyc01(h BIGINT , l BIGINT , v string);

insert into tianyc01 values(1,1,'a');

insert into tianyc01 values(1,2,'b');

insert into tianyc01 values(1,3,'c');

insert into tianyc01 values(1,4,'d');

insert into tianyc01 values(1,5,'e');

insert into tianyc01 values(1,6,'f');

insert into tianyc01 values(2,1,'A');

insert into tianyc01 values(2,2,'B');

insert into tianyc01 values(2,3,'C');

insert into tianyc01 values(2,4,'D');

insert into tianyc01 values(2,5,'E');

insert into tianyc01 values(2,6,'F');

select * from tianyc01;

h l v

1 1 a

1 2 b

1 3 c

1 4 d

1 5 e

1 6 f

2 1 A

2 2 B

2 3 C

2 4 D

2 5 E

2 6 F

②行转列

select h,

split_part(v,',',instr(l,'1')),

split_part(v,',',instr(l,'2')),

split_part(v,',',instr(l,'3')),

split_part(v,',',instr(l,'4')),

split_part(v,',',instr(l,'5')),

split_part(v,',',instr(l,'6'))

from(

select h,WM_CONCAT('',l) as l,WM_CONCAT(',',v) as v from tianyc01

group by h

) x

h _c3 _c4 _c5 _c6 _c7 _c8

------------------------------

1 a b c d e f

2  A B C D E F

在Oracle12C数据库创建wm_concat函数

当我们的程序需要连接12C数据库时,原本使用wm_concat函数的地方会出现报错,这是由于12C已经摒弃了wm_concat这个函数,可以采取的办法有使用listagg函数代替wm_concat函数,但是程序中所有涉及wm_concat函数的地方都得改成listagg函数的写法,所以为了减小修改程序的工作量,可以通过手工创建wm_concat函数来解决这个问题。

一、用sys用户以SYSDBA身份登录数据库,执行以下命

CREATE OR REPLACE TYPE WM_CONCAT_IMPL AS OBJECT
-- AUTHID CURRENT_USER AS OBJECT
(
CURR_STR VARCHAR2(32767), 
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER
);
/
--定义类型body
CREATE OR REPLACE TYPE BODY WM_CONCAT_IMPL
IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
RETURN NUMBER
IS
BEGIN
SCTX := WM_CONCAT_IMPL(NULL) ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF(CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ‘,‘ || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURNVALUE := CURR_STR ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL)
RETURN NUMBER
IS
BEGIN
IF(SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ‘,‘ || SCTX2.CURR_STR ;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
/
--自定义函数列表
CREATE OR REPLACE FUNCTION wm_concat(P1 VARCHAR2)
RETURN VARCHAR2 AGGREGATE USING WM_CONCAT_IMPL ;
/

二、创建同义词并授权

create public synonym WM_CONCAT_IMPL for sys.WM_CONCAT_IMPL
/
create public synonym wm_concat for sys.wm_concat
/

grant execute on WM_CONCAT_IMPL to public
/
grant execute on wm_concat to public
/

以上是关于wm_concat函数的排序问题的主要内容,如果未能解决你的问题,请参考以下文章

oracle的wm_concat函数如何对参数进行排序?请仔细看需求

incepter中支持wm_concat函数吗?

文本聚合函数(wm_concat, listagg, group_concat, string_agg)

如何使用子查询和 wm_concat 对 Oracle SQL 中的数据进行排序

2015.12.24(圣诞节) 解决Oralce数据库将具有相同属性的多行合并为一行的简单方法多年想要wmsys.wm_concat

在Oracle12C数据库创建wm_concat函数