2012-08-03 4 views
1

좋아, 지금은 다른 쿼리에서 while 루프 내부에 쿼리가 있지만 ... 내가하려는 일을하는보다 효율적인 방법이 있어야합니다. 하나의 쿼리를 통해 아래 스크립트를 수행 할 수 있습니까? 그리고 그것은 더 효율적일까요? 여기에 내가 지금 가지고있는 무엇 (안 실제 코드,하지만 좋은 예)를 (내가 그것을 것 있으리라 믿고있어) : 다음과 같이 PHP - 하위 쿼리를 join으로 대체 하시겠습니까?

$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를 증가시키는 것이 if/else 대신 for 루프에서 수행 될 수 있다는 것을 알고 있습니다.

업데이트 : 버그 당 하나의 행이 필요하며 해당 버그에 대해 영향을받는 모든 브라우저가 포함 된 결과 집합에 열을 추가한다고 추측합니다.

+0

'LIMIT 5'가 필요합니까? 또는 "버그 수"에 관계없이 총 "영향을받는 브라우저"의 수를 제한하는 것이 좋습니까? –

+0

한계 5는 이것이 구현되고있는 특정 페이지에 5 개의 버그 만 표시하기를 원하기 때문입니다. 하지만 영향을받는 브라우저의 총 수를 제한 할 수는 없습니다. 버그가 영향을 미치는 모든 브라우저가 필요하기 때문입니다. – ryanpitts1

+0

David Hirst의 답을 참조하십시오. 'LIMIT 5'는 버그가 아니라 전체 결과를 제한합니다. 그 대신 버그를 제한해야한다면이 일이 복잡해집니다. –

답변

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

+1

예, 조인은 항상 두 테이블의 일치하는 행 쌍마다 최소한 하나의 행을 생성합니다. 각 버그마다 하나의 행만 필요하면 조인 할 테이블을 일치하는 행 하나까지 줄여야합니다. 또한 영향을받는 브라우저가없는 버그 (PHP 에서처럼)를보고 싶다면 LEFT OUTER JOIN을 사용해야합니다. – Barmar

+0

도움을 주셔서 감사합니다! – ryanpitts1

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

찾고 계신가요?

+0

초부터 가장 좋은 :) – d2burke

+0

hehe 예.하지만 버그의 기본 키는 Id라고 가정합니다.) –

+0

내게 공평한 것 같았습니다 – d2burke

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

영향을받는 브라우저가 없어도 버그를 나열하려면 다음을 수행하십시오. 그런데 데이터를 가져올 수없는 열을 나열하는 습관을 갖춰야합니다.

+0

예, 알겠지만, 그것은 내 찌르는 코드에있을 것입니다 ... 이것은 단지 예제 코드였습니다. – ryanpitts1

0

다른 답변은 좋습니다. 당신이 버그의 수를 제한 할 필요 영향을 브라우저의 수를 걱정하지 않는 경우, 이것을 사용이 실제 하위 쿼리입니다

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

참고. 그러나 코드와 달리이 코드는 하나의 명령문에 포함되어 있으므로 더 빨라야합니다.

+0

네, 이것에 대해 생각해 보았지만 항상 이러한 하위 쿼리에 지쳐 있습니다. – ryanpitts1

+0

그래서 나는 'LIMIT'에 대해 물었습니다. 버그를 제한해야한다면 다른 해결책은 없습니다.OTOH, 괜찮은 데이터베이스와 함께 이것은 큰 데이터베이스에서도 느려져서는 안된다. 동일한 작업에 대해 6 개의 쿼리를 시작하는 것보다 확실히 좋습니다. –

관련 문제