在CONTAINS函数中使用JOIN语句

Ale*_*der 4 sql-server join contains sql-like

在SQL Server数据库中,我有一个带有很多INNER JOINs语句的View。最后一个联接使用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  + '%'
Run Code Online (Sandbox Code Playgroud)

我想使用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)
Run Code Online (Sandbox Code Playgroud)

我知道CONTAINS的运行速度比LIKE快,并且无法在JOIN语句中使用CONTAINS。在这种情况下或建议中有什么解决方法吗?提前致谢。

geo*_*dex 6

CONCAT工作完美,我已经用 PostgreSQL 测试过

SELECT *
FROM TABLE_ONE AS a INNER JOIN TABLE_TWO AS b
    ON b.field LIKE CONCAT('%', CONCAT(a.field, '%'));
Run Code Online (Sandbox Code Playgroud)

请参考这里的类似答案


Rom*_*kar 5

不是CONTAINS不是不能在联接中使用。

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

CONTAINS
( { column_name | ( column_list ) | * } 
  ,'<contains_search_condition>'     
[ , LANGUAGE language_term ]
) 
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)