【问题标题】:MySQL join instead of a "nested while loop"MySQL 加入而不是“嵌套的 while 循环”
【发布时间】:2011-07-15 05:20:34
【问题描述】:

这段代码工作得很好,但我不喜欢循环中的while循环的想法。

还有其他更有效的 JOINS 方式吗?

$region_results = mysql_query("SELECT id,region_name FROM regions WHERE page_id='$page_id' ORDER BY position ASC",$con_web) or die (mysql_error());
while($region_rows=mysql_fetch_array($region_results))
{
  $region_id=$region_rows["id"];
  $region_name=$region_rows["region_name"];

  echo "  <li>$region_name\n";
  echo "   <ul>\n";

  $block_results = mysql_query("SELECT id,block_name FROM blocks WHERE region_id='$region_id' ORDER BY position ASC",$con_web) or die (mysql_error());
  while($block_rows=mysql_fetch_array($block_results))
  {
    $block_id=$block_rows["id"];
    $block_name=$block_rows["block_name"];

    echo "    <li>$block_name\n";
    echo "     <ul>\n";

    $object_results = mysql_query("SELECT id,object_name FROM objects WHERE block_id='$block_id' ORDER BY position ASC",$con_web) or die (mysql_error());
    while($object_rows=mysql_fetch_array($object_results))
    {
      $object_id=$object_rows["id"];
      $object_name=$object_rows["object_name"];

      echo "      <li>$object_name</li>\n";
    }

    echo "     </ul>\n";
    echo "    </li>\n";
  }

  echo "   </ul>\n";
  echo "  </li>\n";
}

这段代码产生:

  <li>Left Content
   <ul> 
    <li>Block 1
     <ul> 
      <li>Object 1</li> 
     </ul> 
    </li> 
    <li>Block 2
     <ul> 
      <li>Object 1</li> 
     </ul> 
    </li> 
    <li>Block 3
     <ul> 
      <li>Object 1</li> 
     </ul> 
    </li> 
   </ul> 
  </li> 
  <li>Right Panel
   <ul> 
    <li>Block 1
     <ul> 
      <li>Object 1</li> 
      <li>Object 2</li> 
     </ul> 
    </li> 
   </ul> 
  </li> 

谢谢。

【问题讨论】:

    标签: php mysql loops join


    【解决方案1】:
    SELECT  b.id AS block_id, b.block_name, o.id, o.object_name
    FROM    blocks b
    JOIN    objects o
    ON      o.block_id = b.id
    WHERE   b.region_id = '$region_id'
    ORDER BY
            b.position, b.id, o.position
    

    记录block_id 的值,并在其更改时关闭/打开块标签。

    【讨论】:

    • 这就是我卡住的地方!如何在一次提取中回显结果。让它看起来像我的输出示例?
    • @Lewis: if ($prev_block_id != $rows["block_id"]) { close_and_open_block_tags(); }; @prev_block_id = $rows["block_id"];
    • 感谢您的帮助 Quassnoi。我会试试这个。
    【解决方案2】:

    嵌套的 WHILE 循环并不是效率问题。我认为您的问题更多在于您对数据库进行了很多单独的调用,如果将它们组合起来可能会更有效率。

    尝试使用连接将您的查询组合成一个查询,然后循环检测分组何时更改的行。

    【讨论】:

      【解决方案3】:

      while 中的 while 有什么问题?除非它们不能保证结束,并且如果您只需查询一次就可以避免它们,我认为没有任何问题。

      也许您应该使用more high level API 来完成这项工作。这对您的代码会更好。

      【讨论】:

      • 在循环中执行 SQL 查询是一种性能反模式。如果有 20 个区域,每个区域内有 10 个区块,每个区块内有 10 个对象,需要多少次数据库查询?
      • 当然(+1)。这就是为什么我会使用更高级别的 API 并专注于我的业务逻辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      • 2016-05-13
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      相关资源
      最近更新 更多