SQL Server存储过程:实现匹配全部输入条件的菜谱查询
实现菜谱全匹配存储过程(包含所有输入关键词)
你的核心需求是筛选出包含所有输入关键词的菜谱,关键词可匹配标签名、食材名或食材复数名。原视图recipe_view的结构是每个食材与标签的组合生成一行,这导致同一个关键词会在多行重复出现(比如示例中milk对应2行),直接用COUNT(*)统计会错误计算匹配次数,这就是你尝试的分组方法无结果的原因。
解决方案
需要先对每个菜谱匹配的关键词进行去重,再统计匹配的唯一关键词数量是否等于输入的关键词总数。具体实现代码如下:
PROCEDURE [dbo].[search_include] (@includeTags varchar(max)) AS BEGIN SET NOCOUNT ON; -- 临时表存储拆分后的有效关键词 CREATE TABLE #Keywords (Keyword varchar(100) NOT NULL); INSERT INTO #Keywords (Keyword) SELECT VALUE FROM dbo.split(@includeTags) WHERE VALUE IS NOT NULL AND VALUE <> ''; -- 统计每个菜谱匹配的唯一关键词 WITH RecipeMatches AS ( SELECT DISTINCT rv.recipe_id, k.Keyword FROM recipe_view rv JOIN #Keywords k ON k.Keyword = rv.tag_name OR k.Keyword = rv.ingredient_name OR (rv.ingredient_plural_name IS NOT NULL AND k.Keyword = rv.ingredient_plural_name) ) -- 筛选匹配所有关键词的菜谱并返回信息 SELECT rv.recipe_id, rv.recipe_name, rv.recipe_description FROM recipe_view rv JOIN ( SELECT recipe_id FROM RecipeMatches GROUP BY recipe_id HAVING COUNT(DISTINCT Keyword) = (SELECT COUNT(*) FROM #Keywords) ) valid_recipes ON rv.recipe_id = valid_recipes.recipe_id GROUP BY rv.recipe_id, rv.recipe_name, rv.recipe_description; DROP TABLE #Keywords; END
代码说明
- 临时表
#Keywords:过滤拆分后的空关键词,避免无效匹配逻辑。 - CTE
RecipeMatches:通过关联找出菜谱与匹配关键词的唯一组合,用DISTINCT确保同一个关键词在同一菜谱下仅被计数一次。 - 分组筛选:统计每个菜谱匹配的关键词数量,仅保留数量等于输入关键词总数的菜谱,最后关联视图获取菜谱的名称和描述,并用
GROUP BY去重(因为视图中一个菜谱对应多行食材+标签组合)。
测试验证
- 执行
EXEC search_include @includeTags= 'milk, eggs':示例菜谱的milk(匹配食材名)和eggs(匹配食材复数名)均被匹配,统计数量等于输入关键词数,会返回该菜谱。 - 执行
EXEC search_include @includeTags= 'milk, eggs, cheese':示例菜谱无cheese相关匹配,统计数量不等于输入关键词数,不会返回。
内容的提问来源于stack exchange,提问作者Meoco55
相关产品推荐
相关产品推荐

