在包括oracle之类的字符串之前获取所有内容

时间:2017-10-19 23:59:28

标签: sql oracle substring substr

我需要在包含自身的字符串之前获取所有内容,然后用其他内容替换它。例如,如果我在列中有一个值为28/29/81/732536/1496071,那么我想选择81之前的所有内容,包括它自己,即我想要它从28/29/81并用其他字符串替换它。我试过以下,但我只得到了28/29。

 SELECT SUBSTR(eda.ATTRIBUTE_VALUE, 0, INSTR(eda.ATTRIBUTE_VALUE, '81')-2) AS output, ATTRIBUTE_VALUE
FROM EVENT_DYNAMIC_ATTRIBUTE eda

enter image description here

2 个答案:

答案 0 :(得分:1)

解决方案必须在"令牌" (在您的示例中为' 81')出现在两个斜杠之间,或者在字符串的开头和斜杠之前,或者在字符串末尾的最后一个斜杠之后。它不应该匹配,如果' 81'出现作为"令牌的一部分" (在斜杠之间或在第一个斜杠之前或之后)。此外,如果"令牌"不止一次出现,它应该被替换(前面的所有内容)只有一次,如果它根本不出现,那么原始字符串应该保持不变。

如果这些是规则,那么您可以执行以下显示的操作。如果任何规则不同,则可以修改解决方案以适应。

我创建了一些输入字符串来测试WHERE子句中的所有这些情况。我还创建了"搜索令牌"和#34;替换文本"在WITH子句中的第二个子查询中。整个WITH子句应该被替换 - 它不是解决方案的一部分,它只适用于我自己的测试。在主查询中,您应该使用实际的表名和列名(和/或硬编码文本)。

我使用REGEXP_REPLACE来查找令牌并替换它以及它之前的所有内容(但是斜线之后,如果有的话)带有替换文本。我必须小心搜索令牌之后的斜杠;为此,我在REGEXP_REPLACE中的替换字符串中使用反向引用。

with
  event_dynamic_attribute ( attribute_value ) as (
    select '28/29/81/732536/1496071' from dual union all
    select '29/33/530813/340042/88'  from dual union all
    select '81/6883/3902/81/993'     from dual union all
    select '123/45/6789/81'          from dual
  ),
  substitution ( token, replacement ) as (
    select '81', 'mathguy is great'  from dual
  )
select attribute_value,
       regexp_replace (attribute_value, '(^|.*?/)' || token || '(/|$)',
                                        replacement || '\2', 1, 1) new_attrib_value
from   event_dynamic_attribute cross join substitution
;

ATTRIBUTE_VALUE         NEW_ATTRIB_VALUE                       
----------------------- ----------------------------------------
28/29/81/732536/1496071 mathguy is great/732536/1496071         
29/33/530813/340042/88  29/33/530813/340042/88                  
81/6883/3902/81/993     mathguy is great/6883/3902/81/993       
123/45/6789/81          mathguy is great

答案 1 :(得分:0)

你可以使用这样的东西:

SELECT 'STRING_TO_REPLACE_WITH' || SUBSTR(eda.ATTRIBUTE_VALUE, INSTR(eda.ATTRIBUTE_VALUE, '81') + 2) AS output
FROM EVENT_DYNAMIC_ATTRIBUTE eda;