PHP-用联接替换子查询


PHP - replace subquery with join?

好的,所以现在我在while循环中有一个来自另一个查询的查询。。。但必须有一种更有效的方法来完成我想要做的事情。我可以通过一个查询完成下面的脚本吗?这样会更有效率吗?(我想是的)以下是我现在拥有的(不是真正的代码,而是一个很好的例子):

$sth = $dbh->prepare("SELECT * FROM Bugs LIMIT 5");
$sth->setFetchMode(PDO::FETCH_OBJ);
$sth->execute();
while($row = $sth->fetch()){
    $bugId = $row->id;
    echo 'Bug Name: ' . $row->name;
    echo '<br />';
    echo 'Affected Web Browsers: ';
    $sth2 = $dbh->prepare("SELECT * FROM AffectedBrowsers WHERE BugId = '$bugId'");
    $sth2->setFetchMode(PDO::FETCH_OBJ);
    $sth2->execute();
    $i = 1;
    while($row2 = $sth2->fetch()){
        if($i = 1){
            echo $row2->browser;
        }else{
            echo ', ' . $row2->browser;
        }
        $i++;
    }
}

我的表格如下:1) "Bugs"-此表中列出的每个bug都有一行。2) "AFfectedBrowsers"-此表包含特定bug的所有受影响浏览器。该表通过"AffectedBrowsers"表中的bugId列与"Bugs"表有关系。

注意:我确实意识到,递增$I可以在for循环中完成,而不是在if/else循环中完成。

更新:每个bug只需要一行,我猜在结果集中添加一列,列出该bug的所有受影响浏览器

SELECT * FROM Bugs
INNER JOIN AffectedBrowsers ON Bugs.Id = AffectedBrowsers.BugId
LIMIT 5

这就是你想要的吗?

SELECT * FROM Bugs 
LEFT JOIN AffectedBrowsers 
ON Bugs.BugId = AffectedBrowsers.BugId 
LIMIT 5

如果你想列出bug,即使没有受影响的浏览器。顺便说一下,您应该养成列出不想从中检索数据的列的习惯。

SELECT *
FROM Bugs
INNER JOIN 
(SELECT BugId, GROUP_CONCAT(Browser) Browsers FROM AffectedBrowsers GROUP BY BugId) Aff
ON Bugs.Id = Aff.BugId

其他答案都很好。然而,如果你需要限制错误的数量,而不关心受影响的浏览器的数量,请使用以下方法:

  SELECT *
  FROM AffectedBrowsers
  WHERE BugID IN ( SELECT id FROM Bugs LIMIT 5 )

请注意,这是一个真实的子查询。但是,与您的代码不同,它包含在一个语句中,并且应该仍然更快。