AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 13593
Accepted
db2
db2
Asked: 2012-02-22 10:06:06 +0800 CST2012-02-22 10:06:06 +0800 CST 2012-02-22 10:06:06 +0800 CST

按需模糊查找

  • 772

我们有一个客户表(谁没有?),其中包含许多从业务角度来看是重复的记录。我已经能够创建一个 SSIS 包来执行模糊分组,并报告潜在的重复项。

现在,假设我想在有人进入新客户时进行这种分析。这个想法是对客户姓名(可能还有一些其他基本信息,如邮政编码)执行模糊查找,并在继续创建客户表单之前显示潜在的重复项。

这里明显的问题是模糊分组和查找组件是 SSIS 的一部分。如果我想按需运行这些,我必须做一些疯狂的事情,比如将搜索词放在临时表中,运行 SSIS 包,等待它完成,然后从输出表中获取结果。这会很慢,很痛苦,并且有严重的并发问题。

所以,另一个想法是使用全文索引。在尝试它时,它似乎不适合。它无法捕捉到客户名称的细微拼写错误,或者“Company”与“Corporation”与“Co.”或“Anderson”与“Andersen”以及其他此类变体中不同的名称。

有什么东西可以让 T-SQL 的模糊分组/匹配具有灵活性吗?我可以通过模糊查找来保存标记,但看起来我仍然需要重新实现大部分匹配算法才能使用它们。

sql-server sql-server-2008
  • 1 1 个回答
  • 6226 Views

1 个回答

  • Voted
  1. Best Answer
    Rachel
    2012-02-22T12:30:48+08:002012-02-22T12:30:48+08:00

    过去,我在 .Net CLR 函数中构建了一个“模糊搜索”。该函数的调用方式与调用用户定义函数的方式相同。

    例如,

    select id, name
    from customers
    where dbo.CompareStrings("newCustomerName", customers.name) > .8
    

    只会返回与输入名称有 80% 相似度的客户。

    % 匹配基于将一个值转换为另一个值所需的更改次数,而不是不同的字符数。我们用它来比较地址,发现这更有效,因为使用了许多街道缩写。

    这是我用来比较字符串的代码。我很久以前就这样做了,以至于我不记得如何部署它了,尽管快速搜索会向您展示许多有关如何创建 SQL CLR 函数的文章

    ' Checks two strings against each other and returns a decimal between 0 (doesn't match at all) and 1 (100% match)
    <Microsoft.SqlServer.Server.SqlFunction()> _
    Public Shared Function CompareStrings(ByVal input1 As SqlChars, ByVal input2 As SqlChars) _
    As <SqlFacet(Precision:=10, Scale:=4)> SqlDecimal
    
        If IsNothing(input1) And IsNothing(input2) Then
            Return New SqlDecimal(1.0)
        ElseIf IsNothing(input1) Or IsNothing(input2) Then
            Return New SqlDecimal(0.0)
        End If
    
        Dim s1 As String = New String(input1.Value)
        Dim s2 As String = New String(input2.Value)
    
        If s1.Length = 0 Or s2.Length = 0 Then
            Return New SqlDecimal(1.0)
        Else
            Dim re As New Regex("[^A-Za-z0-9 ]", RegexOptions.IgnorePatternWhitespace Xor RegexOptions.Singleline)
            s1 = re.Replace(s1, "( )\1*", "$1")
            s2 = re.Replace(s2, "( )\1*", "$1")
            s1 = UCase(re.Replace(s1, ""))
            s2 = UCase(re.Replace(s2.ToString, ""))
    
            Dim dif As Integer = GetStringSimilarity(s1, s2)
            Dim max As Integer = s1.Length
            If s2.Length > max Then max = s2.Length
    
            Return New SqlDecimal(1.0 - (dif / max))
        End If
    End Function
    
    ' Compares two strings using the relationship in patterns of letters
    Private Shared Function GetStringSimilarity(ByVal s1 As String, ByVal s2 As String) As Integer
        Dim n As Integer = s1.Length
        Dim m As Integer = s2.Length
        Dim distance(n + 1, m + 1) As Integer
    
        Dim cost As Integer = 0
        If n = 0 Then Return m
        If m = 0 Then Return n
    
        For i As Integer = 0 To n
            distance(i, 0) = i
        Next
        For j As Integer = 0 To m
            distance(0, j) = j
        Next
    
        For i As Integer = 1 To n
            For j As Integer = 1 To m
                If Mid(s2, j, 1) = Mid(s1, i, 1) Then cost = 0 Else cost = 1
                distance(i, j) = Min3(distance(i - 1, j) + 1, distance(i, j - 1) + 1, distance(i - 1, j - 1) + cost)
            Next
        Next
        Return distance(n, m)
    End Function
    
    ' Returns the min of 3 values
    Private Shared Function Min3(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Integer
        Dim min As Integer = x
        If y < min Then min = y
        If z < min Then min = z
        Return min
    End Function
    
    • 2

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve