【问题标题】:MySQL Query to a Zend DB SelectMySQL 查询到 Zend DB Select
【发布时间】:2012-10-31 09:15:04
【问题描述】:

我有一个 MySQL 标准查询,我需要将其转换为 Zend_Db_Select,但我无法让它工作。

我收到此错误:

Select query cannot join with another table

这是查询:

// THE COUNTER
$subselect = $this->table->select()->from(
        array('x' => 'blog_comments'),
        array('x.post_id', new Zend_Db_Expr('count(*) as comments')))
    ->group('post_id');
// THE TOTAL SELECT
$select->from(array('p' => 'blog_posts'), array('p.*'))
       ->setIntegrityCheck(false)
       ->joinLeft(array(
           'x' => $subselect,
           'x.post_id = p.id', 
           array()
           )
       );

如果有人可以转换它,那就太好了,因为我在 select() 模式下需要它,因为我使用 Zend_Pagination

对于那些想要完整 PHP 功能的人:Pastebin 和堆栈跟踪:Pastebin

【问题讨论】:

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


    【解决方案1】:

    您可能需要:setIntegrityCheck(false) - 查看:http://framework.zend.com/manual/1.12/en/zend.db.select.html 了解更多信息

    $select = $this->select()
    ->from(params) 
    ->setIntegrityCheck(false) 
    ->joinLeft(params)
    ->where(params);
    

    【讨论】:

    • 我收到了Error 1064SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS x` ON x.post_id = p.id ORDER BY created_date DESC LIMIT 10' at line 2`
    【解决方案2】:

    正如 Michael 已经提到的,您需要 setIntegrityCheck(false) 才能使用 Zend_Db_Select 与其他表进行连接。

    Error 1064 有点模棱两可,包含各种查询语法问题。所以我建议你把子查询用括号括起来:

    $select->setIntegrityCheck(false)
        ->from(array('p' => 'blog_posts'), array('p.*'))
        ->joinLeft(array(
            'x' => new Zend_Db_Expr("({$subselect})"), 
            'x.post_id = p.id', 
            array()
        ));
    

    如果 that 不能正常工作,那么您的子选择一定有问题。试试echo $subselect;,它将调用__toString() magic method 并显示您的查询。

    【讨论】:

      【解决方案3】:

      表达式是Count(*) 语句,而不是整个子查询。

      $subselect = $this->table->select()->from(
          array('x' => 'blog_comments'),
          array('x.post_id', new Zend_Db_Expr('count(*) as comments'))
      )->group('post_id');
      
      $select->from(array('p' => 'blog_posts'), array('p.*'))
          ->joinLeft(array(
              'x' => $subselect,
              'x.post_id = p.id', 
              array()
          ));
      

      我不确定您是否真的需要子查询。无论如何,从一个简单的加入开始并在此基础上进行构建。

      //getGateway = whatever method used to access the database adapter.
      //SetIntegrityCheck(false) locks the tables from writes allowing tables to be joined
      $select = $this->getGateway()->select()->setIntegrityCheck(false);
      $select->from('blog_posts');//default $cols = *
      $select->join('blog_comments', 'blog_comments.post_id' = 'blog_posts.post_id');//does it really matter what kind of join you use? They all work the same so use whichever you like.
      $select->group('blog_comments.post_id');
      

      一旦查询使用默认值,您就可以对其进行细化,直到它按您想要的方式工作。

      如果您要使用分页器进行查询,count() 表达式有点没用,因为分页器会对每个查询应用限制和偏移量。

      您也可以考虑反向执行此查询。您最好加入另一个方向,或者只在 cmets 表上执行查询。如果没有看到你的结构的其余部分,这有点难以分辨。

      祝你好运。

      【讨论】:

      • 嗯,我忘记指定分页器仅用于对博客文章进行分页。整个事情更多的是使用连接或其他方式为每个帖子计算 cmets...
      • 那么为什么要根据需要使用 where() 对可能是外键或至少是索引的 post_id 进行查询。就我个人而言,我只是使用实体模型中的 getComments() 方法,但看起来你的结构并不支持它。
      • 不,我不支持那种模型。但是我的帖子和评论之间的链接不是外键,它只是一个参考。
      • 即使使用setIntegrityCheck(false),我仍然会收到此错误:Message: Select query cannot join with another table
      • 更新您的问题并将您的查询放在上下文中。你在哪里做查询?在控制器中,在 DbTable 模型中还是在不同类型的模型中?此信息可能有助于解决问题
      【解决方案4】:

      我终于用另一种方式做到了。

      我在视图中使用我的CMW_Model_Comments 来获取帖子 ID 的评论数量。

      // IN MY VIEW
      echo $this->commentor->getCommentCount($post->id);
      
      // IN MY CONTROLLER
      $cmt = new CMW_Model_Comments();
      $this->view->commentor = $cmt;
      

      效果很好!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 2013-01-08
        相关资源
        最近更新 更多