2012-08-03 67 views
1

好的,所以现在我在另一个查询的while循环里面有一个查询......但是有一个更有效的方法来做我想做的事情。我可以通过一个查询完成下面的脚本吗?那会更有效率吗? (我假定这将是)这就是我现在(不是真正的代码,而是一个很好的例子):PHP - 用联接替换子查询?

$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)“错误” - 这个表有一个列出每个错误的行。 2)“AFfectedBrowsers” - 这个表格包含了所有受影响的浏览器的特定错误。此表通过“AffectedBrowsers”表中的bugId列与“Bugs”表关联。

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

更新:我只需要每行一行,并且我猜测在结果集中添加了一列,列出了所有受影响的浏览器。

+0

'极限5'是否必要?或者,无论“错误”的数量是多少,限制“受影响浏览器”总数的数量是否可以? – 2012-08-03 14:34:10

+0

限制5是因为我只想在正在实现的特定页面上显示5个错误。但我无法限制受影响的浏览器总数,因为我需要现在每个浏览器都会有一个错误影响。 – ryanpitts1 2012-08-03 14:35:33

+0

请参阅David Hirst的答案。 “LIMIT 5”限制了总体结果,而不是bug。相反,如果你需要限制错误,这会使事情变得复杂。 – 2012-08-03 14:37:03

回答

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

这给了我我需要的东西。我想唯一的方法是通过子查询而不是联接? – ryanpitts1 2012-08-03 15:16:00

+1

是的,连接总是为两个表中的每对匹配行生成至少一行。如果每个bug只需要一行,则需要将加入的表减少到一个匹配行。另外,如果你想查看没有受影响的浏览器的错误(就像你的PHP一样),你应该使用LEFT OUTER JOIN。 – Barmar 2012-08-03 15:21:24

+0

感谢您的帮助! – ryanpitts1 2012-08-03 15:24:57

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

这是你在找什么?

+0

最好的我靠秒来:) – d2burke 2012-08-03 14:35:56

+0

hehe是的,虽然我假设Bugs主键被称为Id;) – 2012-08-03 14:37:36

+0

是的,对我来说似乎公平 – d2burke 2012-08-03 14:39:00

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

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

+0

是的,我知道,它会在我的prod代码中...这只是示例代码。 – ryanpitts1 2012-08-03 14:47:34

0

其他答案都很好。但是,如果您需要限制臭虫的数量,不关心影响浏览器的数量,使用此:

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

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

+0

是的,想到这个,但我总是厌倦这些子查询。 – ryanpitts1 2012-08-03 14:47:58

+0

这就是为什么我问到“LIMIT”的原因。如果您需要限制错误,我看不到其他解决方案。OTOH,一个体面的数据库,即使有大型数据库,这个速度也不会太慢。这肯定比为同一任务启动六个查询要好。 – 2012-08-04 20:00:48