这是我第一次在这里发帖。我似乎没有找到问题的答案。
所以...我正在为一个学校项目安排一个数据库,这是一本食谱,仅显示可以使用“架子”中的现有元素制作的食谱。 这些成分必须具有精确的成分匹配。
用户:
+---------------+------+----------+----------+
| email | name | lastname | password |
+---------------+------+----------+----------+
| pal@mail.com | John | Potato | password |
| they@mail.com | Mary | Carrot | password |
+---------------+------+----------+----------+
货架:
+---------+------------+---------------+
| shelfID | ingredient | user |
+---------+------------+---------------+
| 1 | 1 | pal@mail.com |
| 2 | 2 | pal@mail.com |
| 3 | 3 | pal@mail.com |
| 4 | 4 | pal@mail.com |
| 5 | 10 | they@mail.com |
| 6 | 12 | they@mail.com |
+---------+------------+---------------+
这是我的recipe_ingredient关系表
食谱成分:
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
| 1 | 10 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 2 |
| 3 | 3 |
| 3 | 15 |
+--------+------------+
我尝试过这个查询:
SELECT
rec_ing.recipe, shf.ingredient, shf.user
FROM
recipes_ingredients AS rec_ing
INNER JOIN
shelf AS shf ON rec_ing.ingredient = shf.ingredient
INNER JOIN
users AS usr ON shf.user = usr.email
WHERE
usr.email = 'pal@mail.com'
返回此表:
+--------+------------+--------------+
| recipe | ingredient | user |
+--------+------------+--------------+
| 1 | 1 | pal@mail.com |
| 1 | 2 | pal@mail.com |
| 1 | 4 | pal@mail.com |
| 2 | 1 | pal@mail.com |
| 2 | 2 | pal@mail.com |
| 2 | 3 | pal@mail.com |
| 2 | 4 | pal@mail.com |
| 3 | 2 | pal@mail.com |
| 3 | 3 | pal@mail.com |
+--------+------------+--------------+
虽然食谱 1 确实包含我架子上的成分,但它也缺少成分 10
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
| 1 | 10 |
| ... | ... |
+--------+------------+
我试图只获得这种结果集。
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
+--------+------------+
因为食谱 2 包含我的书架中的所有元素
我整天都在解决这个问题......可能缺少什么?
最佳答案
这有点棘手,因为您需要按配方聚合当前查询,但您还需要原始查询来获取完整记录。遗憾的是,MySQL 不支持公共(public)表表达式或其他可以为我们提供更简洁查询的功能。
SELECT
rec_ing.recipe,
shf.ingredient,
shf.user
FROM recipes_ingredients AS rec_ing
INNER JOIN shelf AS shf
ON rec_ing.ingredient = shf.ingredient
INNER JOIN users AS usr
ON shf.user = usr.email
INNER JOIN
(
SELECT rec_ing.recipe
FROM recipes_ingredients AS rec_ing
INNER JOIN shelf AS shf
ON rec_ing.ingredient = shf.ingredient
LEFT JOIN users AS usr
ON shf.user = usr.email
WHERE
usr.email = 'pal@mail.com'
GROUP BY rec_ing.recipe
HAVING COUNT(usr.email) = COUNT(*)
) t
ON rec_ing.recipe = t.recipe
WHERE
usr.email = 'pal@mail.com'
这里的基本策略是仅对子查询进行一次附加联接,该子查询标识其中每种成分属于给定用户的所有食谱。关键部分如下:
HAVING COUNT(usr.email) = COUNT(*)
这会检查给定配方的总行数是否与已分配给给定用户的行数匹配。
关于mysql - SQL:给定某些元素的精确行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44937633/