在我的mssql数据库中,我有一个包含文章(id,name,content)的表格,其中包含关键字(id,name)和文章与关键词之间的链接表格ArticleKeywords(articleId,关键字ID,计数)。 Count是文章中该关键字的出现次数。SP查找关键字列表或字符串
我该如何编写一个获取逗号分隔字符串列表的SP,并为我提供按文章中关键字出现次数排序的关键字的文章? 如果文章包含更多关键字,我想总结每个关键字的出现次数。
感谢,拉杜
在我的mssql数据库中,我有一个包含文章(id,name,content)的表格,其中包含关键字(id,name)和文章与关键词之间的链接表格ArticleKeywords(articleId,关键字ID,计数)。 Count是文章中该关键字的出现次数。SP查找关键字列表或字符串
我该如何编写一个获取逗号分隔字符串列表的SP,并为我提供按文章中关键字出现次数排序的关键字的文章? 如果文章包含更多关键字,我想总结每个关键字的出现次数。
感谢,拉杜
虽然我不完全清楚逗号分隔字符串的来源是什么,我想你想要的是一个SP将字符串作为输入并产生所需的结果:
CREATE PROC KeywordArticleSearch(@KeywordString NVARCHAR(MAX)) AS BEGIN...
第一步是将逗号分隔的字符串垂直化为具有行中值的表格。这是一个已在this question和another question中得到广泛处理的问题,因此只需在其中选择一个选项即可。无论您选择哪种方式,都将结果存储在表格变量或临时表格中。
DECLARE @KeywordTable TABLE (Keyword NVARCHAR(128))
-- or alternatively...
CREATE TABLE #KeywordTable (Keyword NVARCHAR(128))
对于查找速度,那就更好了存储KeywordID代替查询只需要找到匹配的ID:
DECLARE @KeywordIDTable TABLE (KeywordID INT)
INSERT INTO @KeywordTable
SELECT K.KeywordID FROM SplitFunctionResult S
-- INNER JOIN: keywords that are nonexistent are omitted
INNER JOIN Keywords K ON S.Keyword = K.Keyword
接下来,你可以去写你的查询。这将是这样的:或
SELECT articleId, SUM(count)
FROM ArticleKeywords AK
WHERE K.KeywordID IN (SELECT KeywordID FROM @KeywordIDTable)
GROUP BY articleID
代替WHERE
你可以使用一个INNER JOIN
。我不认为查询计划会有很大的不同。
非常感谢。你节省了我的一天:) – 2010-11-07 22:26:08
关于MSSQL的一个简单问题:当我在Name ='%'+ name +'%'的内部连接时如何获得索引查找? – 2010-11-07 22:29:51
呃。除非我忽略了某些东西,否则唯一的方法就是将新字符串存储在临时表中:INSERT INTO #temp SELECT'%'+ name +'%'AS derivedname'并定义一个索引:' CREATE INDEX index01 ON #temp(derivedname)'。然后使用'INNER JOIN#temp'。但是你确定你不是指'LIKE'%'+ name +'%''?优化这将是一个不同的故事... – thomaspaulb 2010-11-08 00:20:53
我想我明白你是什么后,所以这里去,(不知道郎您正在使用但)在PHP(从你的描述)我会使用ORDER BY计数DESC查询ArticleKeywords语句(即最高优先) - 显然你可以“通过关键字ID或articleid选择。以非常简单的方式(因为我是 - 简单的&可能比我更好)你可以返回数组,但是从它创建一个字符串有点像这样:
$arraytostring .= $row->keywordID.',';
如果你离开连接表,你可以创建这样的东西:
$arraytostring .= $row->keywordID.'-'.$row->name.' '.$row->content.',';
或者你可以赶上阵列
$array[] = $row->keywordID;
,并创建循环外的字符串。
注意:在文章中有两个名为“name”的字段,在关键字中有一个字段可以更容易地重命名其中一个以避免任何冲突(即假设它们不是相同的内容),即articles name = title和关键字名称=关键字
你从哪里看到OP在使用PHP? – thomaspaulb 2010-11-06 09:46:49
我想这样做是一个存储过程...因为有近百万篇文章...我无法加载它们。我有人可以给我开始的sp如何解析csv关键字并将它们的ID添加到临时表中就足够了 – 2010-11-06 09:52:22
对于清酒或参数,您说您要查找方含关键字富,酒吧和沙札姆的所有文章。
ALTER PROCEDURE spArticlesFromKeywordList
@KeyWords varchar(1000) = 'Foo,Bar,Shazam'
AS
SET NOCOUNT ON
DECLARE @KeyWordInClause varchar(1000)
SET @KeyWordInClause = REPLACE (@KeyWords ,',',''',''')
EXEC(
'
SELECT
t1.Name as ArticleName,
t2.Name as KeyWordName,
t3.Count as [COUNT]
FROM ArticleKeywords t3
INNER JOIN Articles t1 on t3.ArticleId = t1.Id
INNER JOIN Keywords t2 on t3.KeywordId = t2.Id
WHERE t2.KeyWord in (''' + @KeyWordInClause + ''')
ORDER BY
3 descending, 1
'
)
SET NOCOUNT OFF
这也很好。看到他有大约一百万篇文章,最好先将关键字转换为id并在IN子句中使用。 – thomaspaulb 2010-11-08 00:13:02
嗨,你的问题对我来说很清楚,除了“...得到逗号分隔字符串列表”这个短语。它从哪里得到它?手工输入或从其他数据库或文本文件? – thomaspaulb 2010-11-06 09:48:06