4

假设这是我的表:

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

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

例如,1and2有一个A共同点,1ad3有一个B共同点,但4与任何其他行没有任何共同的字符。所以我的查询应该只返回前三行。

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

谢谢!

4

3 回答 3

5

@ABCade:很好的解决方案,但可以在没有任何distinctnor的情况下完成join

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

该查询不会将字符串与额外的行进行比较,因为它会在为当前行找到 1 个匹配项后立即停止比较...

见小提琴。

于 2012-10-16T21:10:46.080 回答
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

是一个小提琴

于 2012-10-16T21:04:34.113 回答
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到外部选择字段列表以查看匹配的字母。

于 2012-10-16T20:41:33.190 回答