不知道如何在PHP中限制内部SQL查询

时间:2018-12-20 01:16:30

标签: php mysql xml xmlwriter

到目前为止,

大量的S / O搜索非常有帮助...以下几乎都可以使用。我的问题是第二个SQL查询返回每个“配方”的所有“成分”-而配方1具有成分A,C,F,配方2具有成分A,G,H。如何限制第二个查询在当前循环中仅返回配方的成分?我将非常感谢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();
?>

这是返回的内容:

<?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>

3 个答案:

答案 0 :(得分:1)

假设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();
?>

由于您已经从配方表中进行选择,因此无需再次从中进行选择。 您可能会像这样简化代码:

<?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();
    ?>

通常,我不建议将变量连接到查询中,但是在这种情况下,这是安全的,因为您已经从数据库中选择了ID。

答案 1 :(得分:0)

这正在消耗资源:

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个提示:

  1. 拒绝自己在from子句中的表名之间使用逗号,并且
  2. 如果一个条件有两个表引用,则该条件属于一个JOIN,例如 recipe .recid = rec_ing .recid(请参阅?每边都有一个表引用等于,这是一个联接条件)

最后一个建议:SQL查询不一定必须是PHP代码中的一行。

答案 2 :(得分:0)

欢迎使用Stackoverflow。 您需要添加 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;