用户定义的函数,有条件地将文本拆分为列 Oracle
User defined function which conditionally splits text into columns Oracle
我是 Oracle 数据库或一般数据库的新手,我遇到了一个案例,这个案例很快变成了一个令人头疼的问题
我有一个查询,该查询对给定客户端的 returns 地址 ID 进行分组,每个地址 ID 都有一个关联类型,我需要在单独的列中显示该类型
我现在的查询returns是这样的:
CLIENT_ID ADDRESS_AGG_TYP
12345 6882|HOME;8273|WORK;3192|OTHER
52345 5523|OTHER;1345|HOME;9547|WORK
74563 4431|OTHER;6456|WORK;7567|HOME
34534 1543|WORK;5634|HOME;5123|OTHER
ADDRESS_AGG_TYP - 是一个 LISTAGG,在 address_id 的连接之上按客户端 ID 分组并从地址
键入
Table 的 ddl 可能看起来有点像这样。
CREATE TABLE addresses
( address_id number(*) primary key,
client_id number(*),
type varchar2(70),
address_line_1 varchar2(70),
address_line_2 varchar2(70)
);
我需要将输出转换成这样:
CLIENT_ID HOME WORK OTHER
12345 6882 8273 3192
52345 1345 9547 5523
74563 7567 6456 4431
34534 5634 1543 5123
关于如何实现这一目标的任何想法?我猜这可能需要某种用户定义的函数,但我似乎无法理解这些。
这是在 Oracle DB 版本 12 C 上
这是一种使用正则表达式和指令执行此操作的方法。
首先我附加了一个';'到字符串的开头,如数据块中所示。
我将正则表达式定义为以 ; 开头的模式后跟数字并以 \HOME 或 \WORK 或 \OTHER 结尾。
然后我从提取的部分进一步切分得到数字
with data
as (
select 12345 as client_id,';'||'6882|HOME;8273|WORK;3192|OTHER' as address_agg_typ from dual union all
select 52345 as client_id,';'||'5523|OTHER;1345|HOME;9547|WORK' as address_agg_typ from dual union all
select 74563 as client_id,';'||'4431|OTHER;6456|WORK;7567|HOME' as address_agg_typ from dual union all
select 34534 as client_id,';'||'1543|WORK;5634|HOME;5123|OTHER' as address_agg_typ from dual
)
select client_id
,substr(
regexp_substr(address_agg_typ,';[0-9]*\|HOME')
,2
,instr(regexp_substr(address_agg_typ,';[0-9]*\|HOME'),'HOME')
-3
) as home_extract
,substr(
regexp_substr(address_agg_typ,';[0-9]*\|WORK')
,2
,instr(regexp_substr(address_agg_typ,';[0-9]*\|WORK'),'WORK')
-3
) as work_extract
,substr(
regexp_substr(address_agg_typ,';[0-9]*\|OTHER')
,2
,instr(regexp_substr(address_agg_typ,';[0-9]*\|OTHER'),'OTHER')
-3
) as other_extract
from data
+-----------+--------------+--------------+---------------+
| CLIENT_ID | HOME_EXTRACT | WORK_EXTRACT | OTHER_EXTRACT |
+-----------+--------------+--------------+---------------+
| 12345 | 6882 | 8273 | 3192 |
| 52345 | 1345 | 9547 | 5523 |
| 74563 | 7567 | 6456 | 4431 |
| 34534 | 5634 | 1543 | 5123 |
+-----------+--------------+--------------+---------------+
db fiddle link
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=41a7a4fb3286326b1cb0baf1512aca1b
我是 Oracle 数据库或一般数据库的新手,我遇到了一个案例,这个案例很快变成了一个令人头疼的问题
我有一个查询,该查询对给定客户端的 returns 地址 ID 进行分组,每个地址 ID 都有一个关联类型,我需要在单独的列中显示该类型
我现在的查询returns是这样的:
CLIENT_ID ADDRESS_AGG_TYP
12345 6882|HOME;8273|WORK;3192|OTHER
52345 5523|OTHER;1345|HOME;9547|WORK
74563 4431|OTHER;6456|WORK;7567|HOME
34534 1543|WORK;5634|HOME;5123|OTHER
ADDRESS_AGG_TYP - 是一个 LISTAGG,在 address_id 的连接之上按客户端 ID 分组并从地址
键入Table 的 ddl 可能看起来有点像这样。
CREATE TABLE addresses
( address_id number(*) primary key,
client_id number(*),
type varchar2(70),
address_line_1 varchar2(70),
address_line_2 varchar2(70)
);
我需要将输出转换成这样:
CLIENT_ID HOME WORK OTHER
12345 6882 8273 3192
52345 1345 9547 5523
74563 7567 6456 4431
34534 5634 1543 5123
关于如何实现这一目标的任何想法?我猜这可能需要某种用户定义的函数,但我似乎无法理解这些。
这是在 Oracle DB 版本 12 C 上
这是一种使用正则表达式和指令执行此操作的方法。
首先我附加了一个';'到字符串的开头,如数据块中所示。
我将正则表达式定义为以 ; 开头的模式后跟数字并以 \HOME 或 \WORK 或 \OTHER 结尾。
然后我从提取的部分进一步切分得到数字
with data
as (
select 12345 as client_id,';'||'6882|HOME;8273|WORK;3192|OTHER' as address_agg_typ from dual union all
select 52345 as client_id,';'||'5523|OTHER;1345|HOME;9547|WORK' as address_agg_typ from dual union all
select 74563 as client_id,';'||'4431|OTHER;6456|WORK;7567|HOME' as address_agg_typ from dual union all
select 34534 as client_id,';'||'1543|WORK;5634|HOME;5123|OTHER' as address_agg_typ from dual
)
select client_id
,substr(
regexp_substr(address_agg_typ,';[0-9]*\|HOME')
,2
,instr(regexp_substr(address_agg_typ,';[0-9]*\|HOME'),'HOME')
-3
) as home_extract
,substr(
regexp_substr(address_agg_typ,';[0-9]*\|WORK')
,2
,instr(regexp_substr(address_agg_typ,';[0-9]*\|WORK'),'WORK')
-3
) as work_extract
,substr(
regexp_substr(address_agg_typ,';[0-9]*\|OTHER')
,2
,instr(regexp_substr(address_agg_typ,';[0-9]*\|OTHER'),'OTHER')
-3
) as other_extract
from data
+-----------+--------------+--------------+---------------+
| CLIENT_ID | HOME_EXTRACT | WORK_EXTRACT | OTHER_EXTRACT |
+-----------+--------------+--------------+---------------+
| 12345 | 6882 | 8273 | 3192 |
| 52345 | 1345 | 9547 | 5523 |
| 74563 | 7567 | 6456 | 4431 |
| 34534 | 5634 | 1543 | 5123 |
+-----------+--------------+--------------+---------------+
db fiddle link
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=41a7a4fb3286326b1cb0baf1512aca1b