如何从#KEYWORDS表读取关键词,实现SQL动态关键词标记查询?
动态关键词匹配并标记的最优实现方案
核心思路是通过关联#TABLE和#KEYWORDS表替代硬编码CASE语句,实现关键词动态加载,不用改查询代码,更新关键词表即可生效。
方案1:返回第一个匹配的关键词
如果只需要标记任意一个匹配的关键词(可优先匹配长关键词避免短词覆盖),用CROSS APPLY实现:
-- 清空结果表(按需执行) TRUNCATE TABLE #RESULTS_TABLE; -- 插入匹配结果 INSERT INTO #RESULTS_TABLE (原表其他字段, 匹配关键词) SELECT t.*, k.words AS 匹配关键词 FROM #TABLE t CROSS APPLY ( SELECT TOP 1 words FROM #KEYWORDS WHERE CHARINDEX(words, t.Description) > 0 -- 可选:按关键词长度倒序,优先匹配更长的关键词 ORDER BY LEN(words) DESC ) k;
方案2:返回所有匹配的关键词(合并为字符串)
如果需要把所有匹配的关键词都列出来,分版本实现:
SQL Server 2017及以上版本(用STRING_AGG)
TRUNCATE TABLE #RESULTS_TABLE; INSERT INTO #RESULTS_TABLE (原表其他字段, 匹配关键词列表) SELECT t.*, STRING_AGG(k.words, ', ') AS 匹配关键词列表 FROM #TABLE t LEFT JOIN #KEYWORDS k ON CHARINDEX(k.words, t.Description) > 0 GROUP BY t.主键字段, t.其他需保留字段; -- 必须按原表唯一键或所有非聚合字段分组
兼容SQL Server 2016及更早版本(用XML PATH)
TRUNCATE TABLE #RESULTS_TABLE; INSERT INTO #RESULTS_TABLE (原表其他字段, 匹配关键词列表) SELECT t.*, STUFF( (SELECT ', ' + k.words FROM #KEYWORDS k WHERE CHARINDEX(k.words, t.Description) > 0 FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '' ) AS 匹配关键词列表 FROM #TABLE t;
性能优化建议
- 给#KEYWORDS的
words字段建非聚集索引,加快匹配速度;如果#TABLE数据量极大,可给Description字段建全文索引,用CONTAINS替代CHARINDEX,性能提升更明显:
之后匹配条件改为:-- 先启用全文目录(首次执行) CREATE FULLTEXT CATALOG ftCatalog AS DEFAULT; -- 给#TABLE的Description字段建全文索引(需指定主键索引) CREATE FULLTEXT INDEX ON #TABLE(Description) KEY INDEX PK_TABLE_主键;WHERE CONTAINS(t.Description, k.words) - 如果关键词包含
%、_这类特殊字符,用CHARINDEX时无需转义,比LIKE更省心。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

