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

发布于 2024-11-09 09:08:56 字数 2560 浏览 3 评论 0原文

我有一个相当复杂的 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< /code> 都是 Zend_Db_Select 对象。

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

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

但这似乎只是附加到选择查询上,而不是仅返回指定的列。

因此 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

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

I have a fairly complex query in SQL that performs a count across two tables. The query should look like this:

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

Unfortunately when I have the following code using Zend_Db the query includes a load of additional columns so the addition of both queries obviously fails:

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

Where $pages_total_count_select and $legal_resources_total_count_select are both Zend_Db_Select objects.

I have tried using the columns() method to specify the columns I want on each select object like so:

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

But this just appears to append onto the select query rather than only returning the column specified.

So the Zend generated query ends up looking like this:

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

How can I get rid of all the extra columns it is selecting?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

庆幸我还是我 2024-11-16 09:08:56

您忘记了构建 $pages_total_count_select$legal_resources_total_count_select 的代码部分。

您在构建这些参数的过程中错过了一个参数,即您想要的列数组,如果您不提供它,它将需要 table.*。

因此,只需检查创建选择的方式并添加一个带有空数组的参数即可。

更新:
所以你可以这样做:

$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')));

You forgot one part of your code, where you construct the $pages_total_count_select and $legal_resources_total_count_select.

You missed one parameter in the way to build these, which is the array of columns you want, if you do not give it it takes table.*.

So just check the way you create the select and add one argument with an empty array.

UPDATE:
So you do:

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

Just after that redo a ->from() call with your Zend_Db_Table ($this here) here you can specify the columns, so an empty array or the only one you want:

$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->from($this, array(new Zend_Db_Expr('COUNT(documents.id) AS count')));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文