我有一个表格,其中有一个列为nvarchar(max)
,其中的文字从文档中提取。我怎样才能创建一个选择查询,我会传递另一个关键字列表作为参数,并返回按匹配数量排序的行?用于匹配关键字的SQL查询?
也许这是可能与全文搜索?
我有一个表格,其中有一个列为nvarchar(max)
,其中的文字从文档中提取。我怎样才能创建一个选择查询,我会传递另一个关键字列表作为参数,并返回按匹配数量排序的行?用于匹配关键字的SQL查询?
也许这是可能与全文搜索?
是的,可能与全文检索,并有可能最好的答案。对于直接的T-SQL解决方案,您可以使用拆分功能并加入,例如假设所谓的dbo.Numbers号码表(你可能需要决定在不同的上限):
SET NOCOUNT ON;
DECLARE @UpperLimit INT;
SET @UpperLimit = 200000;
WITH n AS
(
SELECT
rn = ROW_NUMBER() OVER
(ORDER BY s1.[object_id])
FROM sys.objects AS s1
CROSS JOIN sys.objects AS s2
CROSS JOIN sys.objects AS s3
)
SELECT [Number] = rn - 1
INTO dbo.Numbers
FROM n
WHERE rn <= @UpperLimit + 1;
CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers([Number]);
和使用数字该表中的划分功能:
CREATE FUNCTION dbo.SplitStrings
(
@List NVARCHAR(MAX)
)
RETURNS TABLE
AS
RETURN
(
SELECT DISTINCT
[Value] = LTRIM(RTRIM(
SUBSTRING(@List, [Number],
CHARINDEX(N',', @List + N',', [Number]) - [Number])))
FROM
dbo.Numbers
WHERE
Number <= LEN(@List)
AND SUBSTRING(N',' + @List, [Number], 1) = N','
);
GO
然后你就可以简单地说:
SELECT key, NvarcharColumn /*, other cols */
FROM dbo.table AS outerT
WHERE EXISTS
(
SELECT 1
FROM dbo.table AS t
INNER JOIN dbo.SplitStrings(N'list,of,words') AS s
ON t.NvarcharColumn LIKE '%' + s.Item + '%'
WHERE t.key = outerT.key
);
作为顺序:
CREATE PROCEDURE dbo.Search
@List NVARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT key, NvarcharColumn /*, other cols */
FROM dbo.table AS outerT
WHERE EXISTS
(
SELECT 1
FROM dbo.table AS t
INNER JOIN dbo.SplitStrings(@List) AS s
ON t.NvarcharColumn LIKE '%' + s.Item + '%'
WHERE t.key = outerT.key
);
END
GO
然后你可以通过@List
(例如来自C#的文件编号为EXEC dbo.Search @List = N'foo,bar,splunge'
)。
这会不会是超级快,但我敢肯定,这将是比所有的数据拉出到C#和双嵌套循环它手动更快。
谢谢!但那是什么UpperLimit? – Gustav
您希望传递给@List的最长字符串的长度。或者您希望用于其他目的的最大数量(Numbers表对于许多功能非常方便 - 请参阅http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-numbers- table.html)。如果不清楚,请不要在每次运行查询时创建Numbers表 - Numbers表和函数只应创建一次。 –
how to ... return the rows ordered by the number of [full-text] matches
我没有用它自己,而是相信SQL Server 2008支持加权的CONTAINSTABLE相匹配,这可能是对你有所帮助:
http://msdn.microsoft.com/en-us/library/ms189760.aspx
如果没有发动机是返回结果的点击次数加权...
你可以写一个UDF,它有两个输入,并返回一个整数:大textvalue是第一个输入和字Y你在寻找一个逗号分隔的字符串是第二个。该函数返回一个整数,表示不同的查找单词,这些单词在文本中至少发现一次,或查找单词的总次数。实施 - 如何减肥 - 取决于你。例如,你可能希望按照最重要或最不重要的顺序来排列所查找的单词,并且让一个重要的单词比一个不太重要的单词更重要。
然后,您可以使用您的全文搜索引擎来查找包含的话至少一个(你会或它们)的所有记录,而你运行这个结果,通过你的UDF标量函数设置:
pseudo code
select title, weightfunction(summary, 'word1,word2,word3....wordN')
from docs
where summary contains (word1 or word2 or word3 ... or wordN)
order by weightfunction(summary, 'word1,word2,word3....wordN') desc
你试过什么了吗? – msarchet
是的...我选择所有的行,并在C#中手动执行...生产系统非常慢 – Gustav
@Gustav你能展示你在C#中尝试过什么吗? – reggie