如何改进以下mysql选择?

时间:2013-06-23 17:21:46

标签: php mysql zend-db zend-db-select

我目前正在重构遗留应用程序并逐块转换为zend framework 1.12。

我正在摸索如何将其转换为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 个答案:

答案 0 :(得分: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。

答案 1 :(得分: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();
}