英文:
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_ingredient
的ingredients_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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论