我有以下结构的数据库:
表成分(成分名称,颜色)
TABLE食谱(recipe_name)
表recipes_ingredients_parts(recipe_name,ingredient_name,parts)
我想要的是获得与所选成分及其数量相对应的配方。所以我首先尝试的是查询:
SELECT rr.* FROM
(SELECT r.* FROM receipes r
INNER JOIN receipes_ingredients_parts ri
ON r.receipe_name = ri.receipe_name
AND ri.ingredient_name = 'espresso'
AND ri.parts_number = '1') rr;
我得到的是{" Americano"," Espresso"}。但那应该是#34; Espresso"只是因为" Americano"应该有查询:
SELECT rr.* FROM
(SELECT r.* FROM receipes r
INNER JOIN receipes_ingredients_parts ri
ON r.receipe_name = ri.receipe_name
AND ri.ingredient_name = 'espresso'
AND ri.parts_number = '1') rr
INNER JOIN receipes_ingredients_parts ri
ON rr.receipe_name = ri.receipe_name
AND ri.ingredient_name = 'water'
AND ri.parts_number = '4';
接下来我的想法是改变配方表并为每种配料添加列以存储配方的数量。但它将近20列。因此,我对自己以糟糕的方式做工作的想法感到困惑。也许我应该为此目的使用一些好的查询?你们对这些东西有什么想法吗?
答案 0 :(得分:1)
我认为这正是您所寻找的,它应该找到包含您列表中所有成分的receipe_names,而不是其他成分。
SELECT receipe_name
, SUM(CASE
WHEN (ingredient_name, parts_number) IN (('espresso','1'))
THEN 1 ELSE 0
END
) AS matchedIngredients
, SUM(CASE
WHEN (ingredient_name, parts_number) NOT IN (('espresso','1'))
THEN 1 ELSE 0
END
) AS otherIngredients
FROM receipes_ingredients_parts
GROUP BY receipe_name
HAVING matchedIngredients = 1 AND otherIngredients = 0
更通用的版本/模板:
SELECT aField
, SUM(CASE
WHEN someField IN ([matchList])
THEN 1
ELSE 0
END
) AS matches
, SUM(CASE
WHEN someField NOT IN ([matchList])
THEN 1
ELSE 0
END
) AS others
FROM aTable
GROUP BY aField
HAVING matches = [# of values in matchlist]
AND others = 0
或者,如果匹配列表中的项目可能会在表格中重复,并且#34; aField"值:
SELECT aField
, COUNT(DISTINCT CASE
WHEN someField IN ([matchList])
THEN someField
ELSE NULL
END
) AS matches
, COUNT(DISTINCT CASE
WHEN someField NOT IN ([matchList])
THEN someField
ELSE NULL
END
) AS others
FROM aTable
GROUP BY aField
HAVING matches = [# of values in matchlist]
AND others = 0