我正在尝试创建一个存储过程,该过程进行搜索并根据匹配项计算分数。
DECLARE @Search VARCHAR(MAX) = 'John Doe Washington';
SELECT
[address].Name,
[address].Street,
[address].City,
[address].ZipCode,
[address].Country,
IIF([address].[Name] LIKE '%'+@Search+'%', 1000, 0)
+ IIF([address].[Street] LIKE '%'+@Search+'%', 800, 0)
+ IIF([address].[City] LIKE '%'+@Search+'%', 750, 0)
+ IIF([address].[ZipCode] LIKE '%'+@Search+'%', 300, 0)
+ IIF([address].[Country] LIKE '%'+@Search+'%', 250, 0) AS [Score]
FROM [dbo].[Addresses] AS [address];
如果我只是使用例如Name
列中可能包含“ John Doe”。
但是我想稍后用逗号分割@Search
参数,该参数与我发现here的函数[dbo].[splitstring](@stringToSplit VARCHAR(MAX))
一起使用。该函数按逗号分割并创建多行。
所以现在我想更改查询,以使多个搜索词都可以使用。
我想要的是一个LIKE IN(SELECT '%'+Value+'%' FROM dbo.splitstring(@Search))
,不幸的是,它在MS SQL Server中不存在。
如果多个单词与该列匹配,则得分应更高。这意味着该列包含“ John Doe”,第一个单词“ John”匹配1000点,第二个单词“ Doe”匹配另外1000点。第三个是“华盛顿”,它不匹配,所以这个将是0分。
有没有办法做到这一点,或者在MS SQL Server中目前无法做到?
答案 0 :(得分:1)
与其进行LIKE IN (select...
联接,而不是进行联接
cross join (select '%'+Value+'%' as val FROM dbo.splitstring(@Search)) as words
然后您可以对所有行的分数求和
sum(IIF([address].[Name] LIKE val, 1000, 0)
+ IIF([address].[Street] LIKE val, 800, 0)
+ IIF([address].[City] LIKE val, 750, 0)
+ IIF([address].[ZipCode] LIKE val, 300, 0)
+ IIF([address].[Country] LIKE val, 250, 0)
) AS [Score]
哦,然后将函数中的分隔符从逗号更改为空格。
答案 1 :(得分:0)
以i / p程序获取XML。请参考下面的示例。
<data>
<Name>John Doe</Name>
<Street>Cross Road</Street>
<City>Washington</City>
<ZipCode>188255</ZipCode>
<Country>US</Country>
</data>
将此数据插入名称为“名称”,“街道”,“城市”的列的临时表中,并将表与列对列一起应用。
答案 2 :(得分:0)
使用WHERE myColumn LIKE '%word%'
是多余的,因为它与WHERE SUBSTRING('word', myColumn) > 0
完全相同。因此,您的条件是:
WHERE myColumn LIKE IN(SELECT '%'+Value+'%' FROM dbo.splitstring(@Search))
变得可能和容易:
WHERE EXISTS(SELECT 1 FROM dbo.splitstring(@Search)
WHERE SUBSTRING([Value], myColumn) > 0)
此外,您可能需要将表别名添加到子查询myTable.myColumn
中。
答案 3 :(得分:0)
或者,您可以省略自定义功能并使用一个查询(有意地分步编写):
DECLARE @terms nvarchar(MAX) = N'John,Doe,Wood';
WITH SourceTable AS --demo data, skip, use your Addresses table instead
(
SELECT * FROM (VALUES
('John Doe', 'Street'),
('John Cooper', 'Wood')) T(Name,Street)
), Query AS --convert to xml
(
SELECT CAST('<a>'+REPLACE(@terms,',','</a><a>')+'</a>' as xml) Query
), SimpleTerms AS --split to rows
(
SELECT Term.value('.', 'nvarchar(MAX)') Term
FROM Query
CROSS APPLY Query.nodes('a') AS T(Term)
)
SELECT Name,Street,
SUM(IIF(Name LIKE '%'+Term+'%',1000,0)) +
SUM(IIF(Street LIKE '%'+Term+'%',100,0)) Score
--other ingredients
FROM SourceTable
CROSS APPLY SimpleTerms
GROUP BY Name,Street