满足条件时选择所有记录

问题描述 投票:0回答:2

我在让 select 语句正常工作时遇到了一些麻烦。

我有以下表格:

食谱 recipe_ingredient 储藏室
食谱1 成分1 材料1
食谱1 成分2 配料2
食谱2 成分3

我想要一个 select 语句,当用户的储藏室有该食谱的所有成分时返回食谱。

if ($res = $mysqli->query('
SELECT * 
FROM recipe 
WHERE NOT EXISTS (
    SELECT recipe_id 
    FROM recipe_ingredient 
    WHERE NOT EXISTS (
        SELECT ingredient_id 
        FROM pantry 
        WHERE recipe_ingredient.ingredient_id = pantry.ingredient_id 
          AND iduser = ' . $_COOKIE["idUser"] . '
    )
)
')) {

我的代码在数据库中只有一个食谱时有效,但当添加多个食谱时,代码不再有效。以上表为例,它应该返回 recipe1 但它什么也不返回,除非食品储藏室有 ingredient3 然后返回两个食谱。

如何修改我的选择语句来解决这个问题?

php mysql sql having relational-division
2个回答
1
投票

你想要你的用户拥有所有成分的食谱,这看起来像一个关系除法问题。

从原始查询的表名和列名开始,这是一个为您提供食谱 ID 的查询:

select ri.recipe_id
from recipe_ingredient ri 
inner join pantry p on p.ingredient_id = ri.ingredient_id
where p.iduser = ?
group by ri.recipe_id
having count(*) = ( 
    select count(*) 
    from recipe_ingredient ri1 
    where ri1.recipe_id = r.recipe_id
)

想法是过滤用户拥有的配料的配方配料表,然后使用

having
子句确保没有遗漏相同的配方。

旁注:不要在查询中将参数连接为字符串,因为它会打开您的应用程序以进行 SQL 注入;改用绑定参数。


0
投票

您可以使用 exists 执行以下相关子查询,这将测试所有成分是否已填满,这将是当所有 recipe_ingredient ingridents_id 的值不为 NULL

但是您应该知道您的代码容易受到 sql 注入 的影响,因此您应该只使用带参数的准备好的语句,请参阅如何防止 PHP 中的 SQL 注入? 以获取更多信息

SELECT * from recipe r
WHERE NOT EXISTS (SELECT 
                    1 
                FROM recipe_ingredient rp LEFT JOIN pantry ON rp.ingredient_id 
                = p.ingredient_id 
                AND p.iduser= ? 
                WHERE rp.recipe_id = r.recipe_id AND p.ingredient_id IS NULL)
© www.soinside.com 2019 - 2024. All rights reserved.