Sql 列值的oracle查找转换
我有一个数据表如下Sql 列值的oracle查找转换,sql,oracle,function,Sql,Oracle,Function,我有一个数据表如下 create table A (id number, code varchar2(100)); insert into A values (1, '20,21,22'); insert into A values (2, '22,23,24'); commit; 我想用sql来更新表A的代码值和描述 您能为实现这一目标提出一些功能或想法吗 最简单的解决方案是,如果表A的“代码”列中的元素数量是固定的,则通过代码将子查询直接粘贴到“代码描述”表中,我们从枚举
create table A
(id number,
code varchar2(100));
insert into A values
(1, '20,21,22');
insert into A values
(2, '22,23,24');
commit;
我想用sql来更新表A的代码值和描述
您能为实现这一目标提出一些功能或想法吗 最简单的解决方案是,如果表A的“代码”列中的元素数量是固定的,则通过代码将子查询直接粘贴到“代码描述”表中,我们从枚举行中剪切每个代码。最简单的解决方案是,如果表A的“代码”列中的元素数量是固定的,则通过将子查询直接粘贴到代码描述表按代码我们从枚举行中剪切每个代码。您可以标记逗号分隔的列表:
select id, level as rn, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1) as code_id
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null;
ID RN CODE_ID
---------- ---------- -------
1 1 20
1 2 21
1 3 22
2 1 22
2 2 23
2 3 24
然后将其用作CTE子查询分解,并将其加入到我将其设置为左连接的描述中,以便选择如何处理任何缺失的代码:
with cte (id, rn, code_id) as (
select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null
)
select cte.id, cte.rn, cte.code_id, coalesce(cd.code_desc, '??') as code_desc
from cte
left join code_descriptions cd on cd.code_id = cte.code_id;
ID RN CODE_ID CODE_DESC
---------- ---------- ------- ---------
1 1 20 ABC
1 2 21 BBC
2 1 22 CAP
1 3 22 CAP
2 2 23 INC
2 3 24 ABC
然后将这些值聚合回单个逗号分隔的值:
with cte (id, rn, code_id) as (
select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null
)
select cte.id,
listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
from cte
left join code_descriptions cd on cd.code_id = cte.code_id
group by cte.id;
ID CODE
---------- ----------------
1 ABC,BBC,CAP
2 CAP,INC,ABC
然后合并或向我们提供相关更新:
update a
set code = (
with cte (id, rn, code_id) as (
select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null
)
select listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
from cte
left join code_descriptions cd on cd.code_id = cte.code_id
where cte.id = a.id
group by cte.id
);
2 rows updated.
select * from a;
ID CODE
---------- ----------------
1 ABC,BBC,CAP
2 CAP,INC,ABC
或
您可以标记逗号分隔列表:
select id, level as rn, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1) as code_id
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null;
ID RN CODE_ID
---------- ---------- -------
1 1 20
1 2 21
1 3 22
2 1 22
2 2 23
2 3 24
然后将其用作CTE子查询分解,并将其加入到我将其设置为左连接的描述中,以便选择如何处理任何缺失的代码:
with cte (id, rn, code_id) as (
select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null
)
select cte.id, cte.rn, cte.code_id, coalesce(cd.code_desc, '??') as code_desc
from cte
left join code_descriptions cd on cd.code_id = cte.code_id;
ID RN CODE_ID CODE_DESC
---------- ---------- ------- ---------
1 1 20 ABC
1 2 21 BBC
2 1 22 CAP
1 3 22 CAP
2 2 23 INC
2 3 24 ABC
然后将这些值聚合回单个逗号分隔的值:
with cte (id, rn, code_id) as (
select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null
)
select cte.id,
listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
from cte
left join code_descriptions cd on cd.code_id = cte.code_id
group by cte.id;
ID CODE
---------- ----------------
1 ABC,BBC,CAP
2 CAP,INC,ABC
然后合并或向我们提供相关更新:
update a
set code = (
with cte (id, rn, code_id) as (
select id, level, regexp_substr(code, '(.*?)(,|$)', 1, level, null, 1)
from a
connect by level <= regexp_count(code, ',') + 1
and id = prior id
and prior dbms_random.value is not null
)
select listagg(coalesce(cd.code_desc, '??'), ',') within group (order by rn) as code
from cte
left join code_descriptions cd on cd.code_id = cte.code_id
where cte.id = a.id
group by cte.id
);
2 rows updated.
select * from a;
ID CODE
---------- ----------------
1 ABC,BBC,CAP
2 CAP,INC,ABC
或
为什么要存储逗号分隔的值,而不是每个值存储一行?好吧,这就是我们从应用程序到表中获取数据的方式。这不在我的控制范围内。到目前为止,您尝试了什么?考虑创建中间临时表,将列值转换为行,然后连接到描述表进行更新。我想看看是否有更好的方法。为什么要存储逗号分隔的值,而不是每个值存储一行?好吧,这就是我们从应用程序到表中获取数据的方式。这不在我的控制范围内。到目前为止,您尝试了什么?考虑创建中间临时表,将列值转换为行,然后连接到描述表进行更新。我想看看是否有更好的方法,我不明白。请您解释一下。选择id,从代码描述中选择代码描述,其中代码id=子代码,1,指令代码',',1,1-1 | |',','| |从代码描述中选择代码描述,其中代码id=子代码,指令代码',',',1,1+1,指令代码',',1,2-指令代码',',1,1-1 | | |',“| |从代码描述中选择代码描述,其中代码id=子代码,指令代码,”,“,1,2+1来自表|Ai不理解。请您解释一下。选择id,从代码描述中选择代码描述,其中代码id=子代码,1,指令代码',',1,1-1 | |',','| |从代码描述中选择代码描述,其中代码id=子代码,指令代码',',',1,1+1,指令代码',',1,2-指令代码',',1,1-1 | | |',“||从代码描述中选择代码描述,其中代码id=子代码,指令代码,”,“,1,2+1来自表A