问题
In SQL Server database I have a View with a lot of INNER JOINs statements. The last join uses LIKE predicate and that's why it's working too slowly. The query looks 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 + '%'
I want to use CONTAINS instead of LIKE as :
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)
I know that CONTAINS is working faster than LIKE and also that can't use CONTAINS in JOIN statements. Is there any workaround in this case or suggestion? Thanks in advance.
回答1:
It's not that CONTAINS
can't be used in joins.
You just can't use columns as a second parameter of CONTAINS
- see MSDN - CONTAINS (Transact-SQL)
CONTAINS
( { column_name | ( column_list ) | * }
,'<contains_search_condition>'
[ , LANGUAGE language_term ]
)
However, you can use a variable as a search condition, so you can use a cursor and then get all data you need. Here is some very rough example:
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
回答2:
In short there isn't a way to do this using CONTAINS, it simply is not allowed in a JOIN like this. see: TSQL - A join using full-text CONTAINS
So although there is performance hit, IMO like is the easiest solution here.
回答3:
You can create a join using a LIKE.. something like this:
SELECT * FROM TABLE_ONE
FULL OUTER JOIN TABLE_TWO ON TABLE_ONE.String_Column LIKE '%' + TABLE_TWO.Name + '%'
ie - select everything from TABLE_ONE where the string_column is contained in the TABLE_TWO name
来源:https://stackoverflow.com/questions/17448269/using-join-statement-with-contains-function