Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL:给定特定元素的精确行匹配_Mysql_Sql - Fatal编程技术网

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
表,以获得更清晰的信息。我知道这个项目不会像看上去那么简单!谢谢让我更仔细地分析和理解这个答案。这个方法是否需要应用于配方而不是用户?@Kerberos
COUNT(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(*)