如何让Zend_Db仅从大型查询中选择一列?

时间:2011-05-24 09:48:51

标签: php mysql zend-framework zend-db

我在SQL中有一个相当复杂的查询,它在两个表中执行计数。查询应如下所示:

SELECT 
((SELECT COUNT(DISTINCT(pages.id)) AS `count` 
    FROM `pages` 
    INNER JOIN `pageRegions` ON pageRegions.pageId = pages.id 
    WHERE (MATCH (pages.name, pageRegions.contents) AGAINST ('+keyword*' IN BOOLEAN MODE))) + 
(SELECT COUNT(documents.id) AS `count` 
    FROM `documents` 
    INNER JOIN `files` ON files.id = documents.file 
    WHERE (MATCH (documents.name, 
              files.name, 
              files.extracted_text) AGAINST ('+keyword*' IN BOOLEAN MODE)))) AS count

不幸的是,当我使用Zend_Db获得以下代码时,查询包含一些额外的列,因此两个查询的添加显然都会失败:

$total_count_select = $PagesTable->getAdapter()
    ->query('((' . $pages_total_count_select . ') + 
              (' . $legal_resources_total_count_select . ')
             ) AS count');

$pages_total_count_select$legal_resources_total_count_select都是Zend_Db_Select个对象。

我尝试使用columns()方法在每个选择对象上指定我想要的列,如下所示:

$legal_resources_total_count_select->columns('COUNT(documents.id) AS count');

但这只是附加到select查询而不是只返回指定的列。

所以Zend生成的查询最终看起来像这样:

SELECT ((SELECT `pages`.*, 
                 ((1.3 * (MATCH(pages.name) AGAINST ('+keyword*' IN BOOLEAN MODE))) + 
                       (0.8 * (MATCH(pageRegions.contents) AGAINST ('+keyword*' IN BOOLEAN MODE)))) AS `score`, 
                     `pages`.`name` AS `page_name`, 
                     `pages`.`id` AS `page_id`, 
                     `pageRegions`.*, 
                     COUNT(DISTINCT(pages.id)) AS `count`
         FROM `pages`
         INNER JOIN `pageRegions` ON pageRegions.pageId = pages.id
         WHERE (MATCH (pages.name, pageRegions.contents) AGAINST ('+keyword*' IN BOOLEAN MODE))
         ORDER BY `score` DESC)

            + 

          (SELECT `documents`.*,
                   ((1.3 * (MATCH(documents.title) AGAINST ('+keyword*' IN BOOLEAN MODE))) + 
                       (0.8 * (MATCH(documents.short_description, files.NAME, files.extracted_text) AGAINST ('+keyword*' IN BOOLEAN MODE)))) AS `score`,
                     `files`.*, 
                    COUNT(documents.id) AS `count`
         FROM `documents`
         INNER JOIN `files` ON files.id = documents.file
         WHERE (MATCH (documents.title, documents.short_description, files.name, files.extracted_text) AGAINST ('+keyword*' IN BOOLEAN MODE))
         ORDER BY `score` DESC)
        ) AS COUNT

如何摆脱它选择的所有额外列?

1 个答案:

答案 0 :(得分:1)

您忘记了代码的一部分,即构建$pages_total_count_select$legal_resources_total_count_select

你错过了构建这些参数的方法中的一个参数,这是你想要的列数组,如果你不给它它需要表。*。

因此,只需检查创建select的方式,并添加一个带空数组的参数。

<强>更新 所以你这样做:

$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART);

在重做之后用你的Zend_Db_Table(这里是$ this)进行->from()调用,你可以指定列,所以一个空数组或你想要的唯一一个:

$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->from($this, array(new Zend_Db_Expr('COUNT(documents.id) AS count')));