首页 > 解决方案 > oracle select查询中的嵌套替换

问题描述

我需要在返回列值时用它们的实际值替换某些 id 值。并且该列有多个用逗号连接的 id。

我打算做的当前方法如下使用嵌套替换:

select
    REPLACE(REPLACE(REPLACE('1,2,3','1','One'),'2','Two'),'3','Three') as content_types,
    packid,
    packsender
from packages;

我总共有 6 个这样的键值对,所以我需要 6 个嵌套的替换函数。请建议这是否是正确的方法,还有其他更好的方法。

注意:我尝试对表格进行规范化,但是还有很多其他因素阻止了这种情况,所以我必须在没有规范化的情况下得出这个解决方案。

编辑:快速澄清:我使用 1,2,3 作为参考,但键是 5 个字符的字母数字唯一组合,因此不会有任何部分替换的情况。

我拥有的示例列数据:CT002,CT004,CT006

我期待的输出:ContentType2、ContentType4、ContentType6

谢谢,维奈。

标签: sqloracleoracle11g

解决方案


在将说明添加到原始帖子之后,这是解决问题的一种方法。

假设:输入字符串是逗号分隔的标记列表(没有多余的空格、制表符等);一些标记可能等于CT002CT004CT006,这些标记必须分别替换为ContentType2ContentType4ContentType6,同时保持其他所有内容不变。

这可以通过一个正则表达式来完成。该解决方案更易于维护;但它可能仍然比重复(嵌套)调用 REPLACE 慢。如果速度成为问题,两种方法都应该在实际数据上进行测试,看看哪个表现更好。

在我为测试创建的示例数据中(在WITH子句中,它不是 SQL 查询的一部分 - 使用您的实际表和列名),特别注意最后一行 - 看看如果令牌可能包含 CT002 会发生什么(例如) 作为子字符串。此外,第二行显示了由空格包围的令牌CT002,而不是立即被逗号包围;在这种情况下,它不会被替换。我举这些例子来说明以 100% 的精度和准确度指定数据格式的重要性。

正则表达式非常基本;您可能不熟悉正则表达式中的子表达式,以及它们可以在第三个参数中引用的方式regexp_replace()- 请参阅文档(或搜索“正则表达式中的子表达式”以获得更一般的概念,无论甲骨文)。

with
  sample_data (str) as (
    select 'ABC3,CT001,CT006,WHYNOT'       from dual union all
    select 'CT002,CT004,  CT006  , CT93'   from dual union all
    select 'CT002,CT002,CT004,CT002,CT006' from dual union all
    select 'ABCT002'                       from dual
  )
select str,
       regexp_replace(str, 'CT00(2|4|6)(,|$)', 'ContentType\1\2') as new_str
from   sample_data
;

STR                           NEW_STR                                                         
----------------------------- ----------------------------------------------------------------
ABC3,CT001,CT006,WHYNOT       ABC3,CT001,ContentType6,WHYNOT                                  
CT002,CT004,  CT006  , CT93   ContentType2,ContentType4,  CT006  , CT93                       
CT002,CT002,CT004,CT002,CT006 ContentType2,ContentType2,ContentType4,ContentType2,ContentType6
ABCT002                       ABContentType2 

推荐阅读