我有两张桌子,还有一张匹配的桌子。为了争论起见,我们称它们为食谱和配料。每个食谱应该至少有一种成分,但可能有很多。每种成分都可以在许多食谱中使用。
Recipes Ingredients Match
=============== =============== ===============
ID int ID int RecipeID int
Name varchar Name varchar IngredientID int
样本数据:
Recipes Ingredients Match (shown as CDL but stored as above)
=============== =============== ===============
Soup Chicken Soup: Chicken, Tomatoes
Pizza Tomatoes Pizza: Cheese, Chicken, Tomatoes
Chicken Sandwich Cheese C. Sandwich: Bread, Chicken, Tomatoes
Turkey Sandwich Bread T. Sandwich: Bread, Cheese, Tomatoes, Turkey
Turkey
问题是:我需要根据成分的名称对食谱进行排序。鉴于上述示例数据,我需要对食谱进行排序:
Turkey Sandwich (First ingredient bread, then cheese)
Chicken Sandwich (First ingredient bread, then chicken)
Pizza (First ingredient cheese)
Soup (First ingredient chicken)
按第一种成分对食谱进行排名很简单:
WITH recipesranked AS (
SELECT Recipes.ID, Recipes.Name, Recipes.Description,
ROW_NUMBER() OVER (ORDER BY Ingredients.Name) AS SortOrder
FROM
Recipes
LEFT JOIN Match ON Match.RecipeID = Recipes.ID
LEFT JOIN Ingredients ON Ingredients.ID = Match.IngredientID
)
SELECT ID, Name, Description, MIN(SortOrder)
FROM recipesranked
GROUP BY ID, Name, Description;
除此之外,我被困住了。在我上面的例子中,这几乎可以工作,但是两个三明治的顺序不明确。
我有一种感觉MIN(SortOrder)
应该被其他东西取代,也许是一个相关的子查询,寻找同一 CTE 中不存在的另一条记录,但还没有弄清楚细节。
有任何想法吗?
(食谱可能没有成分。我不在乎它们以什么顺序出现,但最后会是理想的。此时不是我主要关心的问题。)
我正在使用 SQL Server 2008 R2。
更新:我为此添加了一个 SQL Fiddle 并更新了此处的示例以匹配:
http://sqlfiddle.com/#!3/38258/2
更新:我有一个偷偷摸摸的怀疑,如果有一个解决方案,它涉及一个交叉连接来比较配方/成分的每个组合,然后以某种方式过滤。