Как я могу заставить Zend_Db выбрать один столбец только из большого запроса? - PullRequest
0 голосов
/ 24 мая 2011

У меня довольно сложный запрос в 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 Ответ

1 голос
/ 24 мая 2011

Вы забыли одну часть своего кода, где вы строите $pages_total_count_select и $legal_resources_total_count_select.

Вы пропустили один параметр в способе их построения, а именно массив столбцов, который вам нужен, если вы его не дадите, он займет таблицу. *.

Так что просто проверьте способ создания выбора и добавьте один аргумент с пустым массивом.

UPDATE: Итак, вы делаете:

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

Сразу после этого повторите вызов ->from() с вашей таблицей Zend_Db_Table ($ this here), здесь вы можете указать столбцы, поэтому вам нужен пустой массив или единственный:

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