mysql - SQL:给定某些元素的精确行匹配

标签 mysql sql

这是我第一次在这里发帖。我似乎没有找到问题的答案。

所以...我正在为一个学校项目安排一个数据库,这是一本食谱,显示可以使用“架子”中的现有元素制作的食谱。 这些成分必须具有精确的成分匹配。

用户:

+---------------+------+----------+----------+
|     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/

相关文章:

MySQL 合并非空值与其他 case when 和 coalesce 语句冲突 - 不确定如何修复

c# - 我得到数据绑定(bind) : 'System.Data.DataRowView' does not contain a property with the name 'productID'

mysql - 限制条目并截断新条目

php - 更新mysql查询报错

mysql - 创建访问同一个表的多个联接

MySQL查询问题: Can't select columns from another table

php - 将实时视频流式传输到网站

mysql - 在哪些情况下我应该为多列创建一个索引而不是为每一列创建一个单独的索引?

sql - 在没有 OR 条件的情况下高效加入配置单元

java.sql.SQLException 到 'path' 的路径不存在