不知道如何在 PHP 中限制内部 SQL 查询
Don't know how to restrict inner SQL query in PHP
到目前为止,大量 S/O 搜索非常有帮助......下面的 almost 有效。我的问题是第二个 SQL 查询 returns ALL the 'ingredients' for EACH 'recipe' -- 而食谱 #1 有成分 A、C、F,而食谱 #2 有成分 A、G、H。如何将第二个查询限制为 return 仅当前循环中配方的成分?如果有 PHP/SQL 向导的帮助,我将不胜感激。
具有多对多关系的数据库结构:
RECIPE (recid, title)
REC_ING (recid, ingid)
INGREDIENT (ingid, ingredient)
这是我的 PHP 代码:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "recipe";
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$xml = new XMLWriter();
$xml->openURI('stackexch.xml');
$xml->setIndent(2);
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('recipes');
$recipe = $db->query("SELECT * FROM recipe");
foreach ($recipe as $row) {
$xml->startElement('recipe');
$xml->startElement('title');
$xml->writeRaw($row['title']);
$xml->endElement();
$ingredient = $db->query("SELECT ingredient FROM recipe, rec_ing, ingredient WHERE recipe.recid=rec_ing.recid AND ingredient.ingid=rec_ing.ingid");
foreach ($ingredient as $subrow) {
$xml->startElement('ingredient');
$xml->writeRaw($subrow['ingredient']);
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
?>
下面是 returned:
<?xml version="1.0" encoding="UTF-8"?>
<recipes>
<recipe>
<title>Recipe #1</title>
<ingredient>ingredient A</ingredient>
<ingredient>ingredient C</ingredient>
<ingredient>ingredient F</ingredient>
<ingredient>ingredient G</ingredient>
<ingredient>ingredient H</ingredient>
</recipe>
<recipe>
<title>Recipe #2</title>
<ingredient>ingredient A</ingredient>
<ingredient>ingredient C</ingredient>
<ingredient>ingredient F</ingredient>
<ingredient>ingredient G</ingredient>
<ingredient>ingredient H</ingredient>
</recipe>
</recipes>
假设recid是菜谱的id。
试试这个:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "recipe";
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$xml = new XMLWriter();
$xml->openURI('stackexch.xml');
$xml->setIndent(2);
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('recipes');
$recipe = $db->query("SELECT * FROM recipe");
foreach ($recipe as $row) {
$xml->startElement('recipe');
$xml->startElement('title');
$xml->writeRaw($row['title']);
$xml->endElement();
$ingredient = $db->query("SELECT ingredient FROM recipe, rec_ing, ingredient WHERE recipe.recid=rec_ing.recid AND ingredient.ingid=rec_ing.ingid AND recipe.recid = " . $row['recid']);
foreach ($ingredient as $subrow) {
$xml->startElement('ingredient');
$xml->writeRaw($subrow['ingredient']);
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
?>
由于您已经select从菜谱table中获取,因此您不需要再次select。
您可以像这样简化代码:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "recipe";
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$xml = new XMLWriter();
$xml->openURI('stackexch.xml');
$xml->setIndent(2);
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('recipes');
$recipe = $db->query("SELECT * FROM recipe");
foreach ($recipe as $row) {
$xml->startElement('recipe');
$xml->startElement('title');
$xml->writeRaw($row['title']);
$xml->endElement();
$ingredient = $db->query("SELECT ingredient FROM rec_ing, ingredient WHERE ingredient.ingid=rec_ing.ingid AND rec_ing.recid = " . $row['recid']);
foreach ($ingredient as $subrow) {
$xml->startElement('ingredient');
$xml->writeRaw($subrow['ingredient']);
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
?>
通常,我不建议将变量连接到查询中,但在这种情况下它是安全的,因为您已经select从数据库中获取 ID。
这正在消耗资源:
SELECT * FROM recipe
然而你只使用了 [title],为什么拉所有列?
正在为从上面返回的每一行执行此操作:
SELECT ingredient
FROM recipe, rec_ing, ingredient
WHERE recipe.recid=rec_ing.recid AND ingredient.ingid=rec_ing.ingid
但是您可以在一个查询中完成上述两项操作,因此消耗的资源更少:
SELECT r.title, i.ingredient
FROM recipe r
INNER JOIN rec_ing ON r.recid=rec_ing.recid
INNER JOIN ingredient i ON i.ingid=rec_ing.ingid
另请注意,25 多年前,ANSI 正式制定了一组您应该尝试采用的联接。 2 个提示:
- 拒绝自己在 from 子句中 table 的名字和
之间使用逗号
- 如果条件有两个 table 引用,则此条件属于 JOIN,例如 recipe.recid=rec_ing.recid(看到了吗?在等号的每一边都有一个 table 引用,这是一个连接条件)
最后一个建议:SQL 查询不必是 PHP 代码中的单行。
欢迎使用 Whosebug。
您需要添加
RECIPE.recid='.$row['recid']
在 where 子句中。
但是在我看来,您可以仅使用一个查询来简化逻辑。我建议使用内部联接来包含来自多个表的信息。
SELECT *
FROM recipe AS r
INNER JOIN rec_ing AS ri ON ri.recid=r.recid
INNER JOIN INGREDIENT AS i ON i.ingid=ri.ingid;
大量 S/O 搜索非常有帮助......下面的 almost 有效。我的问题是第二个 SQL 查询 returns ALL the 'ingredients' for EACH 'recipe' -- 而食谱 #1 有成分 A、C、F,而食谱 #2 有成分 A、G、H。如何将第二个查询限制为 return 仅当前循环中配方的成分?如果有 PHP/SQL 向导的帮助,我将不胜感激。
具有多对多关系的数据库结构:
RECIPE (recid, title)
REC_ING (recid, ingid)
INGREDIENT (ingid, ingredient)
这是我的 PHP 代码:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "recipe";
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$xml = new XMLWriter();
$xml->openURI('stackexch.xml');
$xml->setIndent(2);
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('recipes');
$recipe = $db->query("SELECT * FROM recipe");
foreach ($recipe as $row) {
$xml->startElement('recipe');
$xml->startElement('title');
$xml->writeRaw($row['title']);
$xml->endElement();
$ingredient = $db->query("SELECT ingredient FROM recipe, rec_ing, ingredient WHERE recipe.recid=rec_ing.recid AND ingredient.ingid=rec_ing.ingid");
foreach ($ingredient as $subrow) {
$xml->startElement('ingredient');
$xml->writeRaw($subrow['ingredient']);
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
?>
下面是 returned:
<?xml version="1.0" encoding="UTF-8"?>
<recipes>
<recipe>
<title>Recipe #1</title>
<ingredient>ingredient A</ingredient>
<ingredient>ingredient C</ingredient>
<ingredient>ingredient F</ingredient>
<ingredient>ingredient G</ingredient>
<ingredient>ingredient H</ingredient>
</recipe>
<recipe>
<title>Recipe #2</title>
<ingredient>ingredient A</ingredient>
<ingredient>ingredient C</ingredient>
<ingredient>ingredient F</ingredient>
<ingredient>ingredient G</ingredient>
<ingredient>ingredient H</ingredient>
</recipe>
</recipes>
假设recid是菜谱的id。 试试这个:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "recipe";
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$xml = new XMLWriter();
$xml->openURI('stackexch.xml');
$xml->setIndent(2);
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('recipes');
$recipe = $db->query("SELECT * FROM recipe");
foreach ($recipe as $row) {
$xml->startElement('recipe');
$xml->startElement('title');
$xml->writeRaw($row['title']);
$xml->endElement();
$ingredient = $db->query("SELECT ingredient FROM recipe, rec_ing, ingredient WHERE recipe.recid=rec_ing.recid AND ingredient.ingid=rec_ing.ingid AND recipe.recid = " . $row['recid']);
foreach ($ingredient as $subrow) {
$xml->startElement('ingredient');
$xml->writeRaw($subrow['ingredient']);
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
?>
由于您已经select从菜谱table中获取,因此您不需要再次select。 您可以像这样简化代码:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "recipe";
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$xml = new XMLWriter();
$xml->openURI('stackexch.xml');
$xml->setIndent(2);
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('recipes');
$recipe = $db->query("SELECT * FROM recipe");
foreach ($recipe as $row) {
$xml->startElement('recipe');
$xml->startElement('title');
$xml->writeRaw($row['title']);
$xml->endElement();
$ingredient = $db->query("SELECT ingredient FROM rec_ing, ingredient WHERE ingredient.ingid=rec_ing.ingid AND rec_ing.recid = " . $row['recid']);
foreach ($ingredient as $subrow) {
$xml->startElement('ingredient');
$xml->writeRaw($subrow['ingredient']);
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
?>
通常,我不建议将变量连接到查询中,但在这种情况下它是安全的,因为您已经select从数据库中获取 ID。
这正在消耗资源:
SELECT * FROM recipe
然而你只使用了 [title],为什么拉所有列?
正在为从上面返回的每一行执行此操作:
SELECT ingredient
FROM recipe, rec_ing, ingredient
WHERE recipe.recid=rec_ing.recid AND ingredient.ingid=rec_ing.ingid
但是您可以在一个查询中完成上述两项操作,因此消耗的资源更少:
SELECT r.title, i.ingredient
FROM recipe r
INNER JOIN rec_ing ON r.recid=rec_ing.recid
INNER JOIN ingredient i ON i.ingid=rec_ing.ingid
另请注意,25 多年前,ANSI 正式制定了一组您应该尝试采用的联接。 2 个提示:
- 拒绝自己在 from 子句中 table 的名字和 之间使用逗号
- 如果条件有两个 table 引用,则此条件属于 JOIN,例如 recipe.recid=rec_ing.recid(看到了吗?在等号的每一边都有一个 table 引用,这是一个连接条件)
最后一个建议:SQL 查询不必是 PHP 代码中的单行。
欢迎使用 Whosebug。
您需要添加
RECIPE.recid='.$row['recid']
在 where 子句中。
但是在我看来,您可以仅使用一个查询来简化逻辑。我建议使用内部联接来包含来自多个表的信息。
SELECT *
FROM recipe AS r
INNER JOIN rec_ing AS ri ON ri.recid=r.recid
INNER JOIN INGREDIENT AS i ON i.ingid=ri.ingid;