SQL:将列拆分为多个单词以搜索用户输入
我想将用户输入的单个单词与表中某列的单个单词进行比较SQL:将列拆分为多个单词以搜索用户输入,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我想将用户输入的单个单词与表中某列的单个单词进行比较 例如,考虑表中的这些行: ID Name 1 Jack Nicholson 2 Henry Jack Blueberry 3 Pontiac Riddleson Jack 假设用户的输入是“Pontiac Jack”。我想为每一场比赛分配权重/等级,所以我不能使用像@SearchString这样的总称 如果庞蒂亚克出现在任何一排,我想给他10分。杰克的每一场比赛都会得到另外10分,以此类推。所以第3排得20分,第1排和第2排得10分
例如,考虑表中的这些行:
ID Name
1 Jack Nicholson
2 Henry Jack Blueberry
3 Pontiac Riddleson Jack
假设用户的输入是“Pontiac Jack”。我想为每一场比赛分配权重/等级,所以我不能使用像@SearchString这样的总称
如果庞蒂亚克出现在任何一排,我想给他10分。杰克的每一场比赛都会得到另外10分,以此类推。所以第3排得20分,第1排和第2排得10分
我已将用户输入拆分为单个单词,并将它们存储到临时表@SearchWords(Word)中
但我想不出一种方法来使用SELECT语句来组合这些内容。也许我走错了方向
干杯,
WT这个怎么样?(这是MySQL语法,我认为您只需替换CONCAT并使用+)
然后,您将得到一个SQL结果,该结果的ID为names表,并包含和该ID匹配的单词数。对于SQL Server,请尝试以下操作:
SELECT Word, COUNT(Word) * 10 AS WordCount
FROM SourceTable
INNER JOIN SearchWords ON CHARINDEX(SearchWords.Word, SourceTable.Name) > 0
GROUP BY Word
您可以通过一个通用的表表达式来计算权重。例如:
--** Set up the example tables and data
DECLARE @Name TABLE (id INT IDENTITY, name VARCHAR(50));
DECLARE @SearchWords TABLE (word VARCHAR(50));
INSERT INTO @Name
(name)
VALUES ('Jack Nicholson')
,('Henry Jack Blueberry')
,('Pontiac Riddleson Jack')
,('Fred Bloggs');
INSERT INTO @SearchWords
(word)
VALUES ('Jack')
,('Pontiac');
--** Example SELECT with @Name selected and ordered by words in @SearchWords
WITH Order_CTE (weighting, id)
AS (
SELECT COUNT(*) AS weighting
, id
FROM @Name AS n
JOIN @SearchWords AS sw
ON n.name LIKE '%' + sw.word + '%'
GROUP BY id
)
SELECT n.name
, cte.weighting
FROM @Name AS n
JOIN Order_CTE AS cte
ON n.id = cte.id
ORDER BY cte.weighting DESC;
使用此技术,如果愿意,还可以对每个搜索词应用一个值。所以你可以让杰克比庞蒂亚克更有价值。这看起来像这样:
--** Set up the example tables and data
DECLARE @Name TABLE (id INT IDENTITY, name VARCHAR(50));
DECLARE @SearchWords TABLE (word VARCHAR(50), value INT);
INSERT INTO @Name
(name)
VALUES ('Jack Nicholson')
,('Henry Jack Blueberry')
,('Pontiac Riddleson Jack')
,('Fred Bloggs');
--** Set up search words with associated value
INSERT INTO @SearchWords
(word, value)
VALUES ('Jack',10)
,('Pontiac',20)
,('Bloggs',40);
--** Example SELECT with @Name selected and ordered by words and values in @SearchWords
WITH Order_CTE (weighting, id)
AS (
SELECT SUM(sw.value) AS weighting
, id
FROM @Name AS n
JOIN @SearchWords AS sw
ON n.name LIKE '%' + sw.word + '%'
GROUP BY id
)
SELECT n.name
, cte.weighting
FROM @Name AS n
JOIN Order_CTE AS cte
ON n.id = cte.id
ORDER BY cte.weighting DESC;
在我看来,最好的办法是在一个单独的表中保存所有单词。例如:
ID Word FK_ID
1 Jack 1
2 Nicholson 1
3 Henry 2
(etc)
此表将使用触发器保持最新,并且在“Word”、“FK_ID”上有一个非聚集索引。那么,生成权重的SQL将是简单而高效的。像这样的东西怎么样
Select id, MAX(names.name), count(id)*10 from names
inner join @SearchWords as sw on
names.name like '%'+sw.word+'%'
group by id
假设名为“名称”的表。
是否考虑使用SQLServer全文检索?是的,我有-它对我们来说不是很好,而且很难将它定制成我们的要求。+ 1用于全文搜索-不一定是SQL Server,但例如LuxeN.NET.美观,优雅的解决方案。我想OP的表格必须有一些东西将单个单词链接回原始搜索短语-因此获得整个短语的分数将非常简单,只需将短语与此连接起来,并将按整个短语分组的单词数相加即可。不错的用户名顺便说一句。。。我最喜欢的XKCD之一:)Select id, MAX(names.name), count(id)*10 from names
inner join @SearchWords as sw on
names.name like '%'+sw.word+'%'
group by id