假设这是我的表:
ID STRING
1 'ABC'
2 'DAE'
3 'BYYYYYY'
4 'H'
我想选择STRING列中至少有一个字符在另一行的STRING变量中的所有行。
例如,1
和2
共有一个A
,1
广告3
共有一个B
,但{ {1}}与任何其他行没有任何共同字符。所以我的查询应该只返回前三行。
我不需要知道它匹配哪条线。
谢谢!
答案 0 :(得分:5)
@ A.B.Cade:很好的解决方案,但可以在没有任何distinct
和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匹配就会停止比较......
答案 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
添加到外部选择字段列表中以查看匹配的字母。