【问题标题】:SQL: Can I use CHARINDEX to return the best match not just the first match?SQL:我可以使用 CHARINDEX 来返回最佳匹配而不仅仅是第一个匹配吗?
【发布时间】:2014-02-18 05:33:32
【问题描述】:

http://sqlfiddle.com/#!6/5ac78/1

不确定那个小提琴是否有用。我想从 CHARINDEX 的连接中返回代码 2。

作为另一个示例,我有一个如下所示的描述表 (dt):

ID      Description                         Code
158     INTEREST                            199
159     INTEREST PAID                       383
160     INTEREST PAYABLE ON     ACCOUNT     384

还有一个主表(mt),其条目如下:

ID      Narrative                       Code
1       INTEREST PAID                   NULL

我需要将主表上的 Code 设置为 383。当我使用 CHARINDEX(dt.Description, mt.Description) > 0 基于 JOIN 执行 INSERT 时,它每次都将 mt.Code 设置为 199。

我如何更新主表以使用 最佳 匹配从描述表中提取代码,而不仅仅是第一个匹配实例?

谢谢!

【问题讨论】:

    标签: sql sql-server join sql-update charindex


    【解决方案1】:

    您可以只使用简单的 JOIN 来查找匹配项,使用 LEFT JOIN 来消除除最长匹配项之外的所有匹配项;

    UPDATE t1 
    SET t1.codeA = t2_1.codeB
    FROM table1 t1
    JOIN table2 t2_1      
      ON CHARINDEX(t2_1.colB, t1.colA) > 0
    LEFT JOIN table2 t2_2 
      ON CHARINDEX(t2_2.colB, t1.colA) > 0
     AND t2_1.codeB <> t2_2.codeB 
     AND LEN(t2_2.colB) > LEN(t2_1.colB)
    WHERE t2_2.colB IS NULL;
    

    An SQLfiddle to test with.

    请注意,(可能)无法使像这样的CHARINDEX 查询(或您的原始查询)使用索引,因此对于大量数据,查询可能会非常慢。

    此外,在对您的生产数据运行 Internet 上随机人员的 SQL 更新之前,请始终先进行测试 :)

    【讨论】:

    • 完美!无论如何我都可以使用...非常感谢!
    【解决方案2】:

    这很尴尬,但似乎有效:

    update table1 
       set codeA = (
          select max(codeB)
          from table2
          where charindex(colB, colA) > 0
         )
    where exists ( 
      select 1 
      from table2
      where charindex(colB, colA) > 0
      );
    

    修改后的小提琴在这里:http://sqlfiddle.com/#!6/5ac78/12

    问题在于知道哪个是返回的“最佳”值。我假设 ID 最大的那一行就是你想要的那一行。

    【讨论】:

    • 经过反思,虽然我用您的小提琴示例解决了技术问题,但在我看来,您的原始问题可能略有不同 - 您正在尝试将文本或部分文本匹配到另一个文本字段。这太疯狂了,几乎不可能清楚地为“最佳”匹配指定你的算法,这将足够简洁以在 SQL 中进行编码。
    • “最佳”值是最接近的值。在我的例子中,利息支付是最好的(和完全匹配的)而不是利息。在小提琴中,如果我的描述表包含 ("I am",1) 和 ("I",2) 的条目,那么 table1 应该为 codeA 中的第一行获得值 1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多