Sql 在字符串之前获取所有内容,包括字符串本身

Sql 在字符串之前获取所有内容,包括字符串本身,sql,oracle,substring,substr,Sql,Oracle,Substring,Substr,我需要在字符串之前获取所有内容,包括它本身,然后用其他内容替换它。例如,如果列中有一个值为28/29/81/732536/149671,那么我想选择81之前的所有内容,包括它本身,也就是说,我想从中选择28/29/81,并用其他字符串替换它。我试过下面的方法,但我只得到28/29 SELECT SUBSTR(eda.ATTRIBUTE_VALUE, 0, INSTR(eda.ATTRIBUTE_VALUE, '81')-2) AS output, ATTRIBUTE_VALUE FROM EV

我需要在字符串之前获取所有内容,包括它本身,然后用其他内容替换它。例如,如果列中有一个值为28/29/81/732536/149671,那么我想选择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

您可以使用以下内容:

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

当“token”(示例中的“81”)出现在两个斜杠之间时,或者正好出现在字符串的开头和斜杠之前,或者正好出现在字符串末尾的最后一个斜杠之后时,解决方案必须起作用。如果“81”作为“标记”的一部分出现(在斜杠之间、第一个斜杠之前或最后一个斜杠之后),则不应匹配。此外,如果“token”出现不止一次,则应仅替换一次(使用之前的所有内容),如果它根本没有出现,则原始字符串应保持不变

如果这些是规则,那么你可以做一些我在下面展示的事情。如果任何规则不同,可以修改解决方案以适应

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

我使用REGEXP_REPLACE查找标记,并用替换文本替换它和它前面的所有内容(但不是它后面的斜杠,如果有)。我必须小心搜索标记后面的斜杠;为此,我在REGEXP_REPLACE中的替换字符串中使用了一个backreference

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

显然,您需要增加第三个参数-将
-2
更改为
+1
左右。但是,如果输入中不存在字符串
'81'
,则会出现问题。然后:您真的想匹配
'/81/'
,而不是
'/19812/'
中的
81
?81可以是/和/之间的任何数字,即它可以是81或3543、543545,在我的查询中,匹配字符串来自一个参数。您不理解我的问题。如果属性_值为
28/29/81/732536
,该值是否匹配
253
?它是
732536
的子字符串-这足以形成匹配吗?您的意思是,您将/字符之间的数字视为段,并询问是否应在这些段中包含部分匹配。我下面的回答假设应该包括部分匹配。如果不应该,那么我可以提出这样的建议:如果你需要匹配'123',你可以在'/'| | | eda.ATTRIBUTE|u VALUE | | |'/'中搜索'/123/',搜索方式与我的答案相同…@mathguy,它应该匹配/和/之间的整数,这给了我类似于“STRING_to|u替换|u为09004”的属性值"1/63911/1509004“,id不会一直是2位数字。我只需要在一个数字前面的所有内容,包括结果中的数字本身。”。数字应仅在/和/之间匹配。基本上,这些都是一个实体的祖先路径,当它被移动到另一个父实体时,我想用新路径替换旧路径到该实体,这样它在移动后会有正确的路径。太棒了,太完美了!!