嵌套在oracle select查询中的替换

时间:2018-08-16 02:38:45

标签: sql oracle oracle11g

我需要在返回列值的同时将某些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

谢谢, 维奈。

1 个答案:

答案 0 :(得分:0)

在原始帖子中添加了澄清之后,这是解决问题的一种方法。

假设:输入字符串是用逗号分隔的令牌列表(没有多余的空格,制表符等);一些令牌可能等于 CT002 CT004 CT006 ,并且这些令牌必须替换为 ContentType2 ContentType4 ContentType6 ,而其他所有内容保持不变。

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

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

regexp非常简单;您可能不熟悉正则表达式中的 subexpressions ,以及它们在regexp_replace()的第三个参数中被引用的方式-请参阅相关文档(或搜索“ subexpression”以更广泛的概念使用“正则表达式”)。

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