【问题标题】:Subquery in PHPPHP中的子查询
【发布时间】:2011-01-14 12:52:30
【问题描述】:

让我们用两个表格举一个简单的例子:

USERS (Id, Name, City)
PLAYERS (Id_Player, Number, Team)

而且我必须在循环中使用子选择进行查询,其中子选择始终相同,所以我想将其分成两个查询并将子选择放在循环之外。

我解释一下。 有效但未优化的方法:

for($i=0;$i<something;$i++)
{
    $res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i 
        AND Id_Player IN (SELECT Id FROM USERS WHERE City='London')");
}

我想做但没用的:

$res1=mysql_query("SELECT Id from USERS where City='London'");
for($i=0;$i<something;$i++)
{
    $res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i 
        AND Id_Player IN **$res1**");
}

谢谢!

【问题讨论】:

  • 为什么要进行两个查询而不是一个?一个带有子选择的查询会比两个独立的查询更快。另外,您能告诉我们您遇到了什么错误吗?

标签: php sql mysql subquery sql-subselect


【解决方案1】:

这样的事情应该可以工作。

<?
$sql = "SELECT Team from PLAYERS 
    JOIN USERS on (Id_player=Id)
    WHERE Number BETWEEN $minID AND $maxID
    AND City='London'
    GROUP BY Team";

$results=mysql_query($sql) or die(mysql_error());


// $results contain all the teams from London
// Use like normal..

echo "<ul>\n";

while($team = mysql_fetch_array($results)){
    echo "\t<li>{$team['Team']}</li>\n";
}

echo "</ul>";

【讨论】:

    【解决方案2】:

    在循环中放置 SQL 查询可能会非常慢并且占用大量资源,请查看在您的 SQL 中使用 JOIN。这并不难,一旦你掌握了窍门,你就可以编写一些非常快速强大的 SQL。

    这是一个很好的教程,值得一看,了解不同类型的 JOIN:
    http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php

    【讨论】:

    • 一个非常好的主意。我的回答更多的是让 OP 使用JOIN;循环查询有时会很糟糕。
    【解决方案3】:

    SELECT PLAYERS.*, USERS.City FROM PLAYERS, USERS WHERE USERS.City='London' AND PLAYERS.Number = $i

    不是最好的方法;也许是LEFT JOIN,但它应该可以工作。不过可能语法错误。

    詹姆斯

    编辑

    警告:这不是最理想的解决方案。请给我一个更具体的查询,我可以为您整理一个join 查询。

    考虑到您的评论,让我们看另一个示例。这将使用 PHP 创建一个列表,我们可以使用 MySQL IN 关键字。

    首先,进行查询:

    $res1 = mysql_query("SELECT Id from USERS where City='London'");

    然后,遍历您的查询并将每个 Id 字段一个接一个地放在逗号分隔的列表中:

    $player_ids = ""; 而($row = mysql_fetch_array($res1)) { $player_ids .= $row['Id'] 。 ","; } $player_ids = rtrim($player_ids, ",");

    您现在应该有一个这样的 ID 列表:

    12, 14, 6, 4, 3, 15, ...

    现在将其放入您的第二个查询中:

    for($i = 0; $i

    此处给出的示例可以针对其特定目的进行改进,但我会尽可能保持开放。

    如果您想创建一个字符串列表,而不是 ID 或其他数字,请修改第一个 while 循环,将其中的行替换为

    $player_ids .= "'" . $row['Id'] . "',";

    如果您能给我您使用的实际查询,我可以想出更好的方法;正如我上面所说,这是一种更通用的做事方式,不一定是最好的。

    【讨论】:

    • 谢谢,但让我们假设 $res1 要复杂得多,并且与循环无关。那么它不会像你说的那样优化,对吧?因为它必须在每次迭代中评估“USERS.City='London'”。谢谢
    【解决方案4】:

    在循环中运行查询不是一个好主意。更好的是获取整个表,然后循环遍历表。

    所以查询会是这样的:

    "SELECT Team from PLAYERS WHERE Number BETWEEN($id, $something) 
            AND Id_Player IN (SELECT Id FROM USERS WHERE City='London')"
    

    【讨论】:

      【解决方案5】:
      $res1=mysql_query("SELECT Id from USERS where City='London'");
      for($i=0;$i<something;$i++)
      {
          $res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i 
              AND Id_Player IN **$res1**");
      }
      

      可以,但是mysql_query() 返回一个结果句柄。它不返回 id 值。任何选择查询,无论它返回多少行或多少行,都返回一个结果语句,而不是一个值。您首先必须使用 mysql_fetch...() 调用之一获取该行,该调用返回该行,然后您可以从中提取 id 值。所以...

      $stmt = mysql_query("select ID ...");
      if ($stmt === FALSE) {
          die(msyql_error());
      }
      if ($stmt->num_rows > 0) {
          $ids = array();
          while($row = mysql_fetch_assoc($stmt)) {
              $ids[] = $row['id']
          }
          $ids = implode(',', $ids)
          $stmt = mysql_query("select TEAM from ... where Id_player IN ($ids)");
          .... more fetching/processing here ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多