请帮忙。
我正在使用SQL Server并熟悉CONTAINS
关键字。
我有一张桌子"表1"列值如
1,'bla1 bla2 bla3 String1 bla4 bla5 bla6 String2 bla7 bla8 bla9'
2,'bla3 String1 bla4 String2 bla7 bla8 bla1'
3,'bla3 String2 bla4 String3'
我有另一张桌子"表2"只有一列,但有动态值,如
1,bla1
2,string1
3,bla3
或
1,string2
2,bla5
3,bla1
4,bla4
我只想根据表2中的所有值返回Table1中的行,表示它不是OR
,而是AND
- Table2中的所有值都应该出现在表1和#中39; s列值(可以按任何顺序)。
在上面的例子中,
,表1中的某个值在表1的列值中不可用。
由于这两个表都是临时表变量,我无法在其上添加FULL-TEXT INDEX
,否则我可以使用
CONTAINS(Column, 'SearchString1 AND SearchString2 AND SearchString3 AND so on')
以下代码可以正常工作,但最多只能搜索2个字符串。超过2,它不工作。例如,如果我在下面的代码中有这样的话
declare @str nvarchar(100) = ' Dr clark Nick '
DECLARE @Tab TABLE(Col NVARCHAR(50))
INSERT INTO @Tab
SELECT ' Dr. Nick Clark' UNION ALL
SELECT ' Dr. Nick SPACE Clark' UNION ALL
SELECT ' Dr. Clark SPACE Nick' UNION ALL
SELECT ' Dr. Clark Nick' UNION ALL
SELECT ' Dr. Nick' UNION ALL
SELECT ' Dr. Clark '
declare @str nvarchar(100) = ' Nick clark '
set @str = ltrim(rtrim(@str))
DECLARE @Search1 VARCHAR(MAX), @Search2 VARCHAR(MAX)
declare @t table(sno int, splitdata nvarchar(100))
insert into @t
SELECT
row_number() over (order by ltrim(rtrim(o.splitdata))) as sno,
ltrim(rtrim(o.splitdata)) AS splitdata
FROM
(SELECT CAST('<X>'+REPLACE(@str,' ','</X><X>')+'</X>' AS XML) AS Filter)F1
CROSS APPLY
( SELECT fdata.D.value('.','varchar(MAX)') AS splitdata
FROM f1.Filter.nodes('X') AS fdata(D)
) O
SELECT @Search1 = COALESCE(@Search1 + '%', '') + Splitdata FROM @t order by sno
SELECT @Search2 = COALESCE(@Search2 + '%', '') + Splitdata FROM @t order by sno desc
select * from @tab where col like '%'+@Search1+'%' or col like '%'+@Search2+'%'
答案 0 :(得分:0)
set nocount on;
declare @Tab table (col nvarchar(50));
insert @Tab (Col)
values (' Dr. Nick Clark')
, (' Dr. Nick SPACE Clark')
, (' Dr. Clark SPACE Nick')
, (' Dr. Clark Nick')
, (' Dr. Nick')
, (' Dr. Clark ');
declare @str nvarchar(100) = ' Nick clark ';
set @str = ' ' + ltrim(rtrim(@str)) + ' ';
with Tally
as (
select row_number() over (order by t1.column_id) as 'N'
from sys.columns t1
join sys.columns t2
on 1=1
)
, Needles
as (
select substring(@str,N+1,charindex(' ',@str,N+1)-N-1) 'Needle'
from Tally
where N < len(@str)
and substring(@str,N,1) = ' '
)
, NotSelected
as (
select tab.col
from @tab tab
join Needles
on 1=1
where charindex(Needles.Needle,tab.col) = 0
)
select Tab.Col
from @Tab Tab
left join NotSelected
on NotSelected.Col = Tab.Col
where NotSelected.Col is null;
好的,所以这是我的方法:我们将您的搜索字符串转换为记录集,以空格分隔。我使用Tally-table方法,但是使用基于sys.columns的Common Table Expression而不是Real tally表...基本上给了一个完整的表,我可以使用它来快速分离你的空间 - 将字符串分隔成记录集。我称之为Needles,因为我们正在@tab haystack中寻找这些针。
我创建了针和干草堆的笛卡尔记录集以及CHARINDEX
中needle
的第一个位置的haystack
值。任何零值都告诉我针头不在大海捞针中。这也是一个名为“NotSelected”的常见表格表达式 - 现在列出了找不到针头的所有@Tab.Col值。
最后,Not Selected行与完整表的左连接将显示所有与Not Selected值不匹配的记录。