【问题标题】:Using JOIN statement with CONTAINS function将 JOIN 语句与 CONTAINS 函数一起使用
【发布时间】:2013-07-01 03:49:40
【问题描述】:

在 SQL Server 数据库中,我有一个包含大量 INNER JOIN 语句的视图。最后一个连接使用 LIKE 谓词,这就是它工作太慢的原因。查询看起来像:

SELECT *
FROM A INNER JOIN
B ON A.ID = B.ID INNER JOIN
C ON C.ID1 = B.ID1 INNER JOIN
...........................
X ON X.Name LIKE '%' + W.Name  + '%' AND
            LIKE '%' + W.Name2  + '%' AND
            LIKE '%' + W.Name3  + '%'

我想使用 CONTAINS 而不是 LIKE 作为:

SELECT *
FROM A INNER JOIN
B ON A.ID = B.ID INNER JOIN
C ON C.ID1 = B.ID1 INNER JOIN
...........................
X ON CONTAINS(X.Name, W.Name) AND
     CONTAINS(X.Name, W.Name2) AND
     CONTAINS(X.Name, W.Name3)

我知道 CONTAINS 比 LIKE 工作得更快,而且不能在 JOIN 语句中使用 CONTAINS。 在这种情况下是否有任何解决方法或建议? 提前致谢。

【问题讨论】:

  • SELECT * FROM tableA AS_a INNER JOIN tableB AS b ON b.field LIKE CONCAT('%', CONCAT(a.field, '%'));

标签: sql-server join contains sql-like


【解决方案1】:

简而言之,没有办法使用 CONTAINS 来做到这一点,在这样的 JOIN 中根本不允许这样做。 见:TSQL - A join using full-text CONTAINS

因此,尽管会影响性能,但 IMO like 是这里最简单的解决方案。

【讨论】:

    【解决方案2】:

    并不是CONTAINS不能用于join。

    您不能将列用作CONTAINS 的第二个参数 - 请参阅MSDN - CONTAINS (Transact-SQL)

    CONTAINS
    ( { column_name | ( column_list ) | * } 
      ,'<contains_search_condition>'     
    [ , LANGUAGE language_term ]
    ) 
    

    但是,您可以使用变量作为搜索条件,因此您可以使用游标然后获取您需要的所有数据。 这是一个非常粗略的例子:

    declare @Name nvarchar(max)
    
    declare @Temp_A table(Name nvarchar(max))
    declare @Temp_B table(Name nvarchar(max))
    
    --=============================================================================================
    insert into @Temp_A (Name)
    select 'Test'
    
    insert into @Temp_B (Name)
    select 'aaaTestaaa'
    
    --=============================================================================================
    -- Query 1 - LIKE
    --=============================================================================================
    select *
    from @Temp_A as A
        inner join @Temp_B as B on B.Name like '%' + A.Name + '%'
    
    --=============================================================================================
    -- Query 2 - CONTAINS
    --=============================================================================================
    declare table_cursor cursor local fast_forward for
        select distinct Name from @Temp_A
    open table_cursor
    while 1 = 1
    begin
        fetch table_cursor into @Name
        if @@fetch_status <> 0 break
    
        select * from @Temp_B where contains(Name, @Name)
    end
    close table_cursor
    deallocate table_cursor
    

    【讨论】:

    • 感谢您的回复。我不熟悉光标。你能给我举个例子,在我的情况下如何使用它?
    • 添加了一些示例(虽然非常近似)
    【解决方案3】:

    您可以使用 LIKE.. 像这样:

    SELECT * FROM TABLE_ONE 
    FULL OUTER JOIN TABLE_TWO ON TABLE_ONE.String_Column LIKE '%' + TABLE_TWO.Name + '%'
    

    ie - 从 TABLE_ONE 中选择所有字符串,其中 string_column 包含在 TABLE_TWO 名称中

    【讨论】:

      【解决方案4】:

      CONCAT 完美运行,我用 PostgreSQL 测试过

      选择 * FROM TABLE_ONE 作为 INNER JOIN TABLE_TWO AS b ON b.field LIKE CONCAT('%', CONCAT(a.field, '%'));

      请参考类似答案here

      【讨论】:

      • 我不知道为什么,但这是唯一适合我的解决方案,其他用于加入子字符串的解决方案由于某种原因不起作用。所以谢谢你。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-25
      • 1970-01-01
      • 2016-11-04
      • 2011-02-08
      • 2019-05-27
      • 2019-09-20
      • 2019-09-20
      相关资源
      最近更新 更多