选择所有记录当满足所有条件时。

huangapple go评论76阅读模式
英文:

Selecting ALL records when condition is met for ALL

问题

以下是您要翻译的部分:

I'm having a bit of trouble with getting a select statement to work correctly.

I have the following tables:

recipe recipe_ingredient pantry
recipe1 ingredient1 Ingredient1
recipe1 ingredient2 Ingredient2
recipe2 ingredient3

I want a select statement that returns recipes when the user's pantry has all ingredients for that recipe.

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"] . '
    )
)
')) {

My code works when only one recipe in the db but when multiple recipes are added the code no longer works. Using the above table as an example it should return recipe1 but it returns nothing unless the pantry has ingredient3 then both recipes are returned.

How do I amend my select statement to fix this?

英文:

I'm having a bit of trouble with getting a select statement to work correctly.

I have the following tables:

recipe recipe_ingredient pantry
recipe1 ingredient1 Ingredient1
recipe1 ingredient2 Ingredient2
recipe2 ingredient3

I want a select statement that returns recipes when the user's pantry has all ingredients for that recipe.

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"] . '
    )
)
')) {

My code works when only one recipe in the db but when muliple recipes are added the code no longer works. Using the above table as an example it should return recipe1 but it returns nothing unless the pantry has ingredient3 then both recipes are returned.

How do I amend my select statement to fix this?

答案1

得分: 2

以下是翻译的代码部分:

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

从你原始查询的表格和列名开始,这里是一个可以为你提供食谱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注入的威胁;而是使用绑定参数。
英文:

You want recipes that your user has all ingredients for, which reads like a relational division problem.

Starting from the tables and columns names of your original query, here is a query that gives you the recipe ids:

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
)

The idea is to filter the recipe ingredient table for ingredients that the user has, and then ensure that none misses in the same recipe, using the having clause.

Side note: do not concatenate parameters as strings in your query, as it opens up your application to SQL injection; using bind parameters instead.

答案2

得分: 0

你可以使用存在关联子查询执行以下操作,该查询将测试所有成分是否已填充,当所有recipe_ingredientingredients_id都具有非NULL值时,条件才满足。

但是,你应该注意到你的代码容易受到SQL注入攻击的威胁,因此你应该只使用带有参数的预处理语句。有关更多信息,请参见:https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php

SELECT * FROM recipe r
WHERE NOT EXISTS (SELECT 
                    1 
                FROM recipe_ingredient rp 
                LEFT JOIN pantry p ON rp.ingredient_id = p.ingredient_id AND p.iduser = ? 
                WHERE rp.recipe_id = r.recipe_id AND p.ingredient_id IS NULL)
英文:

you can do following correlated subquery with exists, which will test if all ingredients are filled up, which woul be when all recipe_ingredient ingridents_id have a value that is Not NULL

But you should be aware that your code is vulnerable to sql injection and so you should only use prepared statements with parameters see https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php for more information

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)

huangapple
  • 本文由 发表于 2023年3月12日 06:31:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75709974.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定