Php 如何改进以下mysql选项?

Php 如何改进以下mysql选项?,php,mysql,zend-db,zend-db-select,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::Fetch

我目前正在重构一个遗留应用程序,并将其逐块转换为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>';
}
$folders\u query=DB::query(“按排序顺序从联系人文件夹中选择*);
而($folders=DB::FetchArray($folders\u query)){
$counts\u total=DB::QueryOne(“选择count(cm.messages\u id)作为总计
从contacts_basics cb,contacts_messages cm
其中cb.contacts_id=cm.contacts_id
和cm.folders_id='“$folders['folders_id']”
和cm.status='1'
和cm.mark='0');
如果($counts_total>0){
$folders_name='。$folders['name'].('.$counts_total.');
}否则{
$folders_name=$folders['name'];
}
回音“
  • ”; }
    是的,您可以在同一个查询中同时执行这两项操作

    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;
    
    这使用了一个
    左外部联接
    ,以确保获得所有文件夹,即使没有消息(原始代码就是这样工作的)。由于
    左外部联接
    ,需要将条件移动到
    on
    子句中


    它还从文件夹中获取所有信息以及总数。如果没有消息,则该文件夹应返回0。

    Gordon的回答中有一个小错误,但多亏了他,我才发现了

    我变了

    contacts_basics cb left outer join
    
    致:

    以下代码按预期工作:

    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();
    }
    

    . . 有趣的这是因为我最初是按照原始查询中的顺序编写连接的。然后我意识到,具有正确字段的表是
    cm
    ,而不是
    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();
    }