在IN子句中计算的REPLACE函数在Oracle SQL 11g中不起作用
我有一个问题,在in子句中计算的替换函数在Oracle SQL 11g中不起作用。我需要的是一个基于SQL的解决方案,因为我所能控制的只是SQL 我收到一个以管道分隔的值列表,例如STR1 | STR2。要将它们转换为要查询的值列表,我使用replace,如下所示,该查询的结果应为1在IN子句中计算的REPLACE函数在Oracle SQL 11g中不起作用,sql,oracle,Sql,Oracle,我有一个问题,在in子句中计算的替换函数在Oracle SQL 11g中不起作用。我需要的是一个基于SQL的解决方案,因为我所能控制的只是SQL 我收到一个以管道分隔的值列表,例如STR1 | STR2。要将它们转换为要查询的值列表,我使用replace,如下所示,该查询的结果应为1 select 1 from dual where 'STR1' in (replace('''STR1|STR2''','|',''',''')) 事实上,我没有得到返回的行。替换在语法上是正确的,并且 本质上,
select 1 from dual where 'STR1' in (replace('''STR1|STR2''','|',''','''))
事实上,我没有得到返回的行。替换在语法上是正确的,并且
本质上,这应该归结为
select 1 from dual where 'STR1' in ('STR1','STR2')
这将得到我想要的结果;但它不适用于替换
我如何才能做到这一点?替换管道仍然会留下一个带有“STR1”、“STR2”的字符串文字,而不是两个单独的列表元素。Replace只是在in子句或其他任何地方不做您想要的事情。IN仍然只看到一个字符串值,与您的搜索字符串不匹配 您可以标记分隔字符串;这是一种常见的方法:
with t as (
select regexp_substr('STR1|STR2', '[^|]+', level) as str
from dual
connect by regexp_substr('STR1|STR2', '[^|]+', level) is not null
)
select 1 from dual where 'STR1' in (select str from t)
CTE将两个列表元素作为单独的行获取,然后您可以使用子查询查看您的值是否在该列表中
或者更简单地使用regexp_查找分隔符之间的值,允许它位于开始或结束处:
select 1 from dual where regexp_like('STR1|STR2', '(^|)' || 'STR1' || '(|$)');
或不带正则表达式,如果将值包装为分隔符:
select 1 from dual where '|' || 'STR1|STR2' || '|' like '%|' || 'STR1' || '|%';
您不需要所有固定值的连接,但我假设您实际上是从其他地方获取这两个字符串,这可能会更清楚它是如何构造比较的。虽然管道分隔符也会让它看起来更混乱…替换管道仍然会留下一个带有“STR1”、“STR2”的字符串文字,而不是两个单独的列表元素。Replace只是在in子句或其他任何地方不做您想要的事情。IN仍然只看到一个字符串值,与您的搜索字符串不匹配 您可以标记分隔字符串;这是一种常见的方法:
with t as (
select regexp_substr('STR1|STR2', '[^|]+', level) as str
from dual
connect by regexp_substr('STR1|STR2', '[^|]+', level) is not null
)
select 1 from dual where 'STR1' in (select str from t)
CTE将两个列表元素作为单独的行获取,然后您可以使用子查询查看您的值是否在该列表中
或者更简单地使用regexp_查找分隔符之间的值,允许它位于开始或结束处:
select 1 from dual where regexp_like('STR1|STR2', '(^|)' || 'STR1' || '(|$)');
或不带正则表达式,如果将值包装为分隔符:
select 1 from dual where '|' || 'STR1|STR2' || '|' like '%|' || 'STR1' || '|%';
您不需要所有固定值的连接,但我假设您实际上是从其他地方获取这两个字符串,这可能会更清楚它是如何构造比较的。虽然管道分隔符也让它看起来更混乱…我也面临同样的问题,并设法以这种方式解决:
SELECT 1 from dual
where 'str1' in (select distinct a.name from
(select trim(substr( the_string
, decode( level, 1, 1, instr(the_string,',',1,level-1)+1)
, decode( instr(the_string,',',1,level), 0, length(the_string), instr(the_string,',',1,level) - decode( level, 1, 0, instr(the_string,',',1,level-1))-1)
)) name
from ( select replace('str1|str2','|',',') the_string ,
replace('str1|srt2','|',',') the_string1
FROM dual )
connect by level <= length(the_string)-length(replace(the_string,','))+1) a)
我也面临同样的问题,并设法以这种方式解决:
SELECT 1 from dual
where 'str1' in (select distinct a.name from
(select trim(substr( the_string
, decode( level, 1, 1, instr(the_string,',',1,level-1)+1)
, decode( instr(the_string,',',1,level), 0, length(the_string), instr(the_string,',',1,level) - decode( level, 1, 0, instr(the_string,',',1,level-1))-1)
)) name
from ( select replace('str1|str2','|',',') the_string ,
replace('str1|srt2','|',',') the_string1
FROM dual )
connect by level <= length(the_string)-length(replace(the_string,','))+1) a)
谢谢Alex,不过我不太明白。请问,如何将其集成到单个SQL语句中?此条件将是更大的单个查询的一部分。没有PLSQL或语言参与。干杯DaveSorry,刚刚看到编辑,将有一个与regexp_喜欢的人Alex,regexp_喜欢似乎做的把戏。非常感谢你的帮助。我会认为你的答案是正确的。干杯Dave@MrTea-第一个选项中没有涉及PL/SQL,只是子查询分解CTE。您可以通过一个大型查询来实现这一点,但这可能会让人感到困惑。第二种或第三种选择可能更合适;如果这是一个大问题,请检查两个问题的性能。谢谢Alex,但我不确定我是否理解这一点。请问,如何将其集成到单个SQL语句中?此条件将是更大的单个查询的一部分。没有PLSQL或语言参与。干杯DaveSorry,刚刚看到编辑,将有一个与regexp_喜欢的人Alex,regexp_喜欢似乎做的把戏。非常感谢你的帮助。我会认为你的答案是正确的。干杯Dave@MrTea-第一个选项中没有涉及PL/SQL,只是子查询分解CTE。您可以通过一个大型查询来实现这一点,但这可能会让人感到困惑。第二种或第三种选择可能更合适;如果是一个大的查询,请检查这两个查询的性能。