PHP中的子查询
Posted
技术标签:
【中文标题】PHP中的子查询【英文标题】:Subquery in PHP 【发布时间】: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**");
谢谢!
【问题讨论】:
为什么要进行两个查询而不是一个?一个带有子选择的查询会比两个独立的查询更快。另外,您能告诉我们您遇到了什么错误吗? 【参考方案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
字段一个接一个地放在逗号分隔的列表中:
您现在应该有一个这样的 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 ...
【讨论】:
以上是关于PHP中的子查询的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 PHP+ODBC 发送包含带有内部连接的子查询的查询?