PHP MySQL配方搜索基于提供的成分

PHP MySQL配方搜索基于提供的成分,php,mysql,database,search,recipe,Php,Mysql,Database,Search,Recipe,比如说,我有一个食谱数据库,我想根据我有什么配料来搜索它们 应该有3个表: 食谱(rid、rname), 成分(iid、iname), 关系(rid,iid) 接下来,让我们假设我有一个“吐司”和一个“面包和黄油布丁”的配方——吐司有两种成分(面包和黄油)——布丁可能有面包和黄油,加上面粉、鸡蛋和水——因此总共有5种 我的问题是,根据搜索中提供的成分构造SQL查询。如果我在搜索中提交3种配料——面包、黄油和鸡蛋——那么(从讨论的2种食谱中)只会产生一个结果——吐司因为没有足够的原料做布丁 那么,

比如说,我有一个食谱数据库,我想根据我有什么配料来搜索它们

应该有3个表:

食谱(rid、rname),
成分(iid、iname),
关系(rid,iid)

接下来,让我们假设我有一个“吐司”和一个“面包和黄油布丁”的配方——吐司有两种成分(面包和黄油)——布丁可能有面包和黄油,加上面粉、鸡蛋和水——因此总共有5种

我的问题是,根据搜索中提供的成分构造SQL查询。如果我在搜索中提交3种配料——面包、黄油和鸡蛋——那么(从讨论的2种食谱中)只会产生一个结果——吐司因为没有足够的原料做布丁


那么,这样的sql查询实际上是什么样子的呢?我尝试了所有的东西,用谷歌搜索了所有的东西,现在我的大脑再也无法处理它了。

假设
iid
的列表已经给出(1,2,3),你可以尝试从
关系中选择所有的东西,其中
iid
位于(1,2,3)而
rid
位于(1,2,3)中(在
relationship
中选择
rids
具有计数

SELECT *
FROM Recipes
WHREE rid NOT IN (SELECT DISTINCT rid FROM Relationship WHERE iid NOT IN (ids))

不知道这是否是最好的方法,但对于您给出的示例,它会起作用:

SELECT
    *
FROM
    recipes
WHERE
    rid NOT IN (
        /* exclude all recipes with other ingredients */
        SELECT rid FROM relationship WHERE iid NOT IN (1, 2, 4)
    )
对不起,我的英语()

编辑:配料ID的顺序与您的问题中的顺序相同,因此1是面包,2是黄油,4是鸡蛋:

“iid”;“iname” “1”;“面包” “2”;“黄油” “3”;“面粉” “4”;“鸡蛋”
“5”;“Water”

我的回答假设您正在使用PDO,但如果使用基本mysql或mysqli调用,您可以根据需要进行修改:

$ingredient1 = $_POST['ingredient1'];
$ingredient2 = $_POST['ingredient2'];
$ingredient3 = $_POST['ingredient3'];

$sql = '
SELECT
 c.rid,
 c.rname
FROM ingredients a
JOIN relationship b ON (a.iid = b.iid)
JOIN recipes c ON (b.rid = c.rid)
WHERE
     (a.iname LIKE ? AND a.iname LIKE ? AND a.iname LIKE ?)
';

$stmt = $db->prepare($sql)
$stmt->execute(array('%'.$ingredient1.'%', '%'.$ingredient2.'%', '%'.$ingredient3.'%'));
当然,我的回答假设您的语句始终包含三个配方,并且您正在使用post变量,但也可以进行修改以适应可变性。与其他类型的查询相比,这种类型的查询的好处是,您不必使用子查询,因为子查询通常效率较低

编辑 忘记在数组值中添加“%”符号。这将匹配相应表中的任何成分名称。如果必须匹配,只需删除“LIKE”和“%”符号并放置“=?”