Mysql SQL:给定特定元素的精确行匹配
这是我第一次在这里发帖。我似乎找不到我问题的答案 所以。。。我正在为一个学校项目安排一个数据库,这是一本食谱,它只展示了可以用“书架”上现有元素制作的食谱。 这些成分必须有精确的成分匹配 用户: 货架:Mysql SQL:给定特定元素的精确行匹配,mysql,sql,Mysql,Sql,这是我第一次在这里发帖。我似乎找不到我问题的答案 所以。。。我正在为一个学校项目安排一个数据库,这是一本食谱,它只展示了可以用“书架”上现有元素制作的食谱。 这些成分必须有精确的成分匹配 用户: 货架: +---------+------------+---------------+ | shelfID | ingredient | user | +---------+------------+---------------+ | 1 | 1 |
+---------+------------+---------------+
| 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 |
+--------+------------+
| 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 |
+--------+------------+
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
+--------+------------+
因为配方2包含了我书架上的所有元素
我整天都在处理这个问题。。。可能会缺少什么?这有点棘手,因为您需要按配方聚合当前查询,但还需要原始查询以获取完整记录。遗憾的是,MySQL不支持公共表表达式或其他特性,这可能会减少查询的详细程度
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(*)
这将检查给定配方的总行数是否与分配给给定用户的行数相匹配。请尝试发布
usr
和shf
表,以获得更清晰的信息。我知道这个项目不会像看上去那么简单!谢谢让我更仔细地分析和理解这个答案。这个方法是否需要应用于配方而不是用户?@KerberosCOUNT(usr.email)
统计给定用户的非NULL
(即匹配)成分的数量。
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(*)