我已经编写了一个查询来提供与相同数据库的匹配,它给了我预期的结果,除了我没有得到它的一小部分。以下是查询:
select f.name, f.id, f.industry, d.name, d.id, d.industry
from product_table f, product_table d
where (f.name like '%' || d.name || '%') and
(f.industrylike '%' || d.industry|| '%') and
我知道通过提供它实际上寻找2列之间的匹配:
(..... like '%' || ..... || '%')
但是它的每个部分究竟做了什么,它意味着什么?
此查询正在执行自联接(此处为交叉自联接),我们在其中为某些目的查询同一个表的两个实例。在这种情况下,它看起来像某种形式的数据质量练习,我们怀疑我们可能会有几乎重复的记录。也就是说,我们认为我们有(产品名称和行业)相同组合的记录。使用通配符将识别一列的值完全嵌入另一列的记录:例如'%STACK%'
匹配'META STACKOVERFLOW'
。
发布的版本有一个潜在的缺陷,如果有两个完全匹配的记录,你会得到两个点击(一个用于F:D,一个用于D:F)。您可以通过在id上添加过滤器来实现这一目标
select f.name, f.id, f.industry,
d.name, d.id, d.industry
from product_table f, product_table d
where (f.name like '%' || d.name || '%')
and (f.industrylike '%' || d.industry|| '%')
and ( ( f.name = d.name
and f.industry = d.industry
and f.id < d.id )
or f.name != d.name
or f.industry != d.industry
)
双垂直条(通常称为管道)是连接运算符。它用于将字符串连接在一起。 (许多编程语言都使用+
,但Oracle严格保留对数字进行算术运算。)
为什么我们在第二列之前和之后放置它并不太明确:f.name喜欢'%'|| d.name || '%'
在这种情况下,查询是连接通配符。鉴于f.name = 'XYZ'
的这个值,我们将获得'%' || d.name || '%'
的匹配:
'1XYZ1'
'11XYZ11'
'11XYZ'
'XYZ1'
'XYZ'
我们不需要在通配符运算符中包装f.name
,因为查询是自连接的,因此name
的所有值都将出现在过滤器的左侧。当f.name = '1XYZ1'
与'%' || d.name || '%'
匹配时:
'1XYZ1'
'XYZ1'
'XYZ'
所以你已经获得了多次点击。将过滤器的两侧嵌入通配符只会产生更多噪声重复。