2013-06-23 2 views
0

Я в настоящее время реорганизую устаревшее приложение и конвертирую часть за частью в zend framework 1.12.Как я могу улучшить следующие варианты mysql?

Я почесываю голову о том, как преобразовать это в 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

Да, вы можете сделать и в том же запросе

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, чтобы убедиться, что вы получите все папки, даже если нет никаких сообщений (что, как исходный код работает). Из-за left outer join условия необходимо переместить в пункты on.

Он также извлекает всю информацию из папок, а также общую сумму. Если сообщений нет, тогда он должен вернуть 0 для этой папки.

0

В ответе Гордона была небольшая ошибка, но я понял это благодаря ему.

Я изменил

contacts_basics cb left outer join 

To:

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'. Одним из решений было бы «правильное внешнее соединение», но я предпочитаю «левое внешнее соединение» (привычки), и, я думаю, я не полностью исправил синтаксис. –