2013-06-23 2 views
0

현재 레거시 애플리케이션을 리팩터링하고 프레임 워크 1.12로 조각을 한 곡씩 변환 중입니다.다음의 MySQL select를 개선하려면 어떻게해야합니까?

나는 이것을 zend db로 변환하는 방법에 관해서 머리를 쓰다듬어보고 있는데, 이것은 하나의 쿼리로 수행 할 수있는 방법일까요?

지금은 폴더 목록을 먼저 가져온 다음 폴더 당 추가 쿼리를 실행하는 것을 볼 수 있습니다. 하나의 쿼리로 실행하면 성능이 향상 될 것입니다. 그렇습니까?

$folders_query = DB::Query("select * from contacts_folders order by sort_order, name"); 
while($folders = DB::FetchArray($folders_query)){ 
    $counts_total = DB::QueryOne("SELECT count(cm.messages_id) AS total 
    FROM contacts_basics cb, contacts_messages cm 
    WHERE cb.contacts_id = cm.contacts_id 
    AND cm.folders_id = '" . $folders['folders_id'] . "' 
    AND cm.status = '1' 
    AND cm.mark = '0'"); 


    if ($counts_total >0){ 
     $folders_name = '<strong>' . $folders['name'] . ' (' . $counts_total . ')</strong>'; 
    } else { 
     $folders_name = $folders['name']; 
    } 

    echo '<li><a href="messages.php?fID=' . $folders['folders_id'] . '">'; 

    echo $folders_name; 

    echo '</a></li>'; 
} 

답변

2

예, 당신이 어떻게 원래의 코드이다 (어떤 메시지가없는 경우에도, 당신은 모든 폴더를 얻을 수 있는지 확인하기 위해 left outer join를 사용

SELECT cf.*, count(cm.messages_id) AS total 
FROM contacts_folders cf left outer join 
    contacts_messages cm 
    on cf.id = cm.folders_id and 
     cm.status = '1' AND cm.mark = '0' left outer join 
    contacts_basics cb 
    on cb.contacts_id = cm.contacts_id 
group by cf.folders_id 
order by cf.sort_order, cf.name; 

같은 쿼리에서 모두 할 수 있습니다 공장). left outer join 때문에 조건을 on 절로 옮길 필요가 있습니다.

또한 폴더의 모든 정보와 총계를 가져옵니다. 메시지가 없으면 해당 폴더에 대해 0을 리턴해야합니다.

0

고든의 대답에 사소한 버그가 있었지만 그 덕분에 알아 냈습니다.

내가에

contacts_basics cb left outer join 

변경 :

left outer join contacts_basics cb 

다음 코드는 예상대로 작동합니다

public function getMenuCounts(){ 
    $raw = "SELECT cf.*, count(cm.messages_id) AS total 
    FROM contacts_folders cf left outer join 
    contacts_messages cm 
    on cf.folders_id = cm.folders_id and 
    cm.status = '1' AND cm.mark = '0' 
    left outer join contacts_basics cb 
    on cb.contacts_id = cm.contacts_id 
    group by cf.folders_id 
    order by cf.sort_order, cf.name;"; 
    $db = Zend_Db_Table::getDefaultAdapter(); 
    $stmt = $db->query($raw); 
    return $stmt->fetchAll(); 
} 
+0

. . 즐거움. 그 이유는 원래 원래 쿼리의 순서대로 조인을 작성했기 때문입니다. 그런 다음 조인의 오른쪽 필드가 'cm'이 아니라 'cb'라는 테이블임을 알게되었습니다. 한 가지 해결책은'오른쪽 외부 조인 '이었을 ​​지 모르지만'왼쪽 외부 조인'(습관)을 선호합니다. 구문을 완전히 고치지는 않았을 것입니다. –

관련 문제