Sql 比较具有单位vs但实际上相同的地址
我正在尝试检索地址1地址2的记录 我遇到了这样一种情况,其中有一些地址类似于以下示例:Sql 比较具有单位vs但实际上相同的地址,sql,sql-server,compare,Sql,Sql Server,Compare,我正在尝试检索地址1地址2的记录 我遇到了这样一种情况,其中有一些地址类似于以下示例: address 1 address 2 69 Cherokee Cir Unit 204 69 CHEROKEE CIR # 204 我的查询返回属于这种情况的记录,但这是不正确的,因为地址实际上是相同的 能否举例说明如何解决这一问题 地址1和地址2的地址值都是完整块,不存储在多列中 以下是如何使用REPLACE进行此操作。但即使两个地址中都有额外的空格,也意味着它
address 1 address 2
69 Cherokee Cir Unit 204 69 CHEROKEE CIR # 204
我的查询返回属于这种情况的记录,但这是不正确的,因为地址实际上是相同的
能否举例说明如何解决这一问题
地址1和地址2的地址值都是完整块,不存储在多列中 以下是如何使用REPLACE进行此操作。但即使两个地址中都有额外的空格,也意味着它们不匹配
declare @Something table
(
address1 varchar(50)
, address2 varchar(50)
)
insert @Something values
('69 Cherokee Cir Unit 204', '69 CHEROKEE CIR # 204')
select *
from @Something s
where s.address1 = replace(s.address2, '#', 'Unit')
以下是您如何使用REPLACE进行此操作。但即使两个地址中都有额外的空格,也意味着它们不匹配
declare @Something table
(
address1 varchar(50)
, address2 varchar(50)
)
insert @Something values
('69 Cherokee Cir Unit 204', '69 CHEROKEE CIR # 204')
select *
from @Something s
where s.address1 = replace(s.address2, '#', 'Unit')
这里有一个计算不同单词的方法。 但它使用了自Sql Server 2017年以来才添加的STRING_SPLIT函数
select t.*
from YourTable t
cross apply
(
select
count(nullif(s1.value,' ')) as diffcnt1
,count(nullif(s2.value,' ')) as diffcnt2
--,string_agg(nullif(s1.value,' '),'|') as diff1,
--,string_agg(nullif(s2.value,' '),'|') as diff2
from string_split(t.address1,' ') s1
full join string_split(t.address2,' ') s2
on lower(s1.value) = lower(s2.value)
where s1.value is null
or s2.value is null
) ca
where t.address1 != t.address2
and (ca.diffcnt1>1 or ca.diffcnt2>1)
对dbfiddle的测试
或者尝试这种快速而肮脏的方法来过滤至少一些相对相似的内容。
还可以检查字符串之间的值
SELECT *
FROM YourTable
WHERE (LOWER(address1) != LOWER(address2))
AND DIFFERENCE(LOWER(address1), LOWER(address2)) < 4
但差异只是比较字符串的SOUNDEX值。所以有可能得到假阳性或假阴性
也许检查字符串之间的距离更准确。
下面是一篇关于在Sql Server中计算该指标的老文章:
还有其他的方法。这里有一种计算不同单词的方法。 但它使用了自Sql Server 2017年以来才添加的STRING_SPLIT函数
select t.*
from YourTable t
cross apply
(
select
count(nullif(s1.value,' ')) as diffcnt1
,count(nullif(s2.value,' ')) as diffcnt2
--,string_agg(nullif(s1.value,' '),'|') as diff1,
--,string_agg(nullif(s2.value,' '),'|') as diff2
from string_split(t.address1,' ') s1
full join string_split(t.address2,' ') s2
on lower(s1.value) = lower(s2.value)
where s1.value is null
or s2.value is null
) ca
where t.address1 != t.address2
and (ca.diffcnt1>1 or ca.diffcnt2>1)
对dbfiddle的测试
或者尝试这种快速而肮脏的方法来过滤至少一些相对相似的内容。
还可以检查字符串之间的值
SELECT *
FROM YourTable
WHERE (LOWER(address1) != LOWER(address2))
AND DIFFERENCE(LOWER(address1), LOWER(address2)) < 4
但差异只是比较字符串的SOUNDEX值。所以有可能得到假阳性或假阴性
也许检查字符串之间的距离更准确。
下面是一篇关于在Sql Server中计算该指标的老文章:
还有其他问题。地址操纵充其量也是非常有问题的。您可以在这里的示例中使用REPLACE进行比较。但在区分大小写的排序中,这些仍然不相同。如果它们除了单位之外不完全相同,它们就不会匹配。Wikipeadia有一篇关于这个问题的好文章:地址操纵充其量是非常有问题的。您可以在这里的示例中使用REPLACE进行比较。但在区分大小写的排序中,这些仍然不相同。如果他们不是完全相同的单位,他们不会匹配。维基百科上有一篇关于这个问题的文章:谢谢你,肖恩,这是一个很好的起点。我一直在努力正确过滤结果,我快疯了。谢谢肖恩,这是一个很好的起点。我一直在努力正确过滤结果,我快发疯了。它只是计算一个介于0和4之间的数字来表示相似度。4表示非常相似。如果他想找到不同的字符串,但避免使用相似的字符串,那么过滤差异为4的字符串并不是一个完美的解决方案。但也许OP会发现这个概念仍然有用,没问题。前一段时间我做了相反的事情,把你的答案看错了。这是常有的事;它只是计算一个介于0和4之间的数字来表示相似度。4表示非常相似。如果他想找到不同的字符串,但避免使用相似的字符串,那么过滤差异为4的字符串并不是一个完美的解决方案。但也许OP会发现这个概念仍然有用,没问题。前一段时间我做了相反的事情,把你的答案看错了。这是常有的事;