字符串内的子串

时间:2012-10-16 20:28:57

标签: oracle

假设这是我的表:

ID  STRING
1   'ABC'
2   'DAE'
3   'BYYYYYY'
4   'H'

我想选择STRING列中至少有一个字符在另一行的STRING变量中的所有行。

例如,12共有一个A1广告3共有一个B,但{ {1}}与任何其他行没有任何共同字符。所以我的查询应该只返回前三行。

我不需要知道它匹配哪条线。

谢谢!

3 个答案:

答案 0 :(得分:5)

@ A.B.Cade:很好的解决方案,但可以在没有任何distinctjoin的情况下完成。

SELECT * FROM test t1
WHERE EXISTS
(
  SELECT * FROM test t2
  WHERE t1.id<>t2.id AND
  regexp_like(t1.string, '['|| replace(t2.string, '.[]', '\.\[\]')||']')
)

查询不会将字符串与额外的行进行比较,因为只要找到当前行的1匹配就会停止比较......

See fiddle.

答案 1 :(得分:4)

@ GolezTrol的答案很好,但这是另一种方法:

select distinct t1."ID", t1."STRING" 
from table1 t1, table1 t2
where t1."ID" <> t2."ID"
and regexp_like(t1."STRING", '['|| t2."STRING"||']')

首先拿一张表的卡西斯产品 然后确保你不要将相同的字符串与自身进行比较 然后从一个字符串创建一个正则表达式以与另一个字符串进行比较 - [<string1>]表示该字符串必须包含[ ]中的一个字母,这些字母全部来自string1

Here是一个小提琴

答案 2 :(得分:1)

像这样:

select distinct
  id, name
from
  (select distinct
    x.id,
    x.NAME,
    length(x.NAME) as leng,
    substr(x.name, level, 1) as namechar
  from
    YourTable x
  start with
    level = 0
  connect by
    level <= length(x.name)) y
where
  exists 
    (select 
      'x' 
    from 
      YourTable z 
    where 
      instr(z.name, y.namechar) > 0 and
      z.id <> y.id)
order by 
  id      

它的作用:

首先,(内部选择)使用带有数字生成器的表,该数字生成器为名称中的每个字母返回一个数字。现在,YourTable中的每条记录都会返回Length(Name)次,每次都有另一个号码。生成的数字用于隔离该字母(substr)。

然后(在顶级where子句中进行子选择)检查是否存在包含该隔离字母的记录。需要区别,因为如果多个字母匹配,则会多次返回记录。您可以将namechar添加到外部选择字段列表中以查看匹配的字母。