Symfony2 Doctrine 错误:无法计算使用 HAVING 子句的查询。使用输出步行器进行分页

Posted

技术标签:

【中文标题】Symfony2 Doctrine 错误:无法计算使用 HAVING 子句的查询。使用输出步行器进行分页【英文标题】:Symfony2 Doctrine error: Cannot count query that uses a HAVING clause. Use the output walkers for pagination 【发布时间】:2015-12-02 15:17:12 【问题描述】:

我正在尝试获取非空的集合,即至少有 1 个对象。 Collection 实体与 Object 实体具有 OneToMany 关系。我正在使用 KNP 分页器对结果进行分页。这是我的功能:

  public function fetchAction(Request $request)
    $em = $this->getDoctrine()->getManager();

    $page = $request->get('page', 1);
    $limit = 10;

    $collections = $em->createQueryBuilder()
        ->select('c')
        ->add('from', 'CollectionBundle:Collection c LEFT JOIN c.object o')
        ->having('COUNT(o.id)>0')
        ->orderBy('c.date', 'DESC')
        ->getQuery();

    $collections = $this->get("knp_paginator")->paginate($collections, $page, $limit);

    return $this->render('CollectionBundle:Collection:fetch.html.twig', [
        'collections' => $collections
    ]);

错误

我不断收到以下错误

 Cannot count query that uses a HAVING clause. Use the output walkers for pagination

没有 'Having' 子句一切正常,但我必须获得非空集合。

【问题讨论】:

【参考方案1】:

wrap-queries 解决了这个问题

 $collections = $this->get("knp_paginator")->paginate($collections, $page, $limit,array('wrap-queries'=>true));

【讨论】:

嗨@gggg 好消息!你能链接一些关于这个参数的文档吗?您能否将您的答案标记为已接受,以便结束您的问题? 6 年后遇到同样的问题,您的回答为我解决了...谢谢。关于这个选项的文档不多,当查看 KNP 组件的代码时,你会发现它,它只是启用了 OutputWalker:.../vendor/knplabs/knp-components/src/Knp/Component/Pager/Event/Subscriber/Paginate/Doctrine/ORM/QuerySubscriber.php$useOutputWalkers = false; if (isset($event->options['wrap-queries'])) $useOutputWalkers = $event->options['wrap-queries']; 这里和@scandel 一样,我真的不知道去哪里正式找这个。谢谢。【参考方案2】:

您可以实现手动计数,如here in the doc 所述。

例如,你可以修改你的代码如下:

$count = $em->createQueryBuilder()
        ->select('COUNT(c)')
        ->add('from', 'CollectionBundle:Collection c LEFT JOIN c.object o')
        ->having('COUNT(o.id)>0')
        ->orderBy('c.date', 'DESC')
        getSingleScalarResult();


    $collections = $em->createQueryBuilder()
        ->select('c')
        ->add('from', 'CollectionBundle:Collection c LEFT JOIN c.object o')
        ->having('COUNT(o.id)>0')
        ->orderBy('c.date', 'DESC')
        ->getQuery();

    $collections->setHint('knp_paginator.count', $count); 

    $collections = $this->get("knp_paginator")->paginate($collections, $page, $limit,array('distinct' => false));

    return $this->render('CollectionBundle:Collection:fetch.html.twig', [
        'collections' => $collections
    ]);

希望有帮助

【讨论】:

注意 ['distinct' => false] 选项,没有它我会出错。【参考方案3】:

我的解决方案基于@Matteo 的解决方案,因为我的查询有点复杂,所以我也想分享我的版本:

$qb = $this->createQueryBuilder('c');
    $qb->select('count(c.id)')
        ->addSelect('COUNT(DISTINCT m.id) AS HIDDEN messageCount')
        ->addSelect('COUNT(DISTINCT f.id) AS HIDDEN fileCount')
        ->join('c.user', 'u')
        ->join('c.status', 's')
        ->join('c.company', 'comp')
        ->leftJoin('c.files', 'f')
        ->leftJoin('c.messages', 'm');

    $this->_set_filters($filter, $qb);
    $qb->groupBy('c.id');
    $countQuery = $qb->getQuery();

    /** wrap query with SELECT COUNT(*) FROM ($sql)
    * I don't know what exactly does this block but
    * I coppied it from Doctrine\ORM\Tools\Pagination\Paginator::getCountQuery()
     */
    $platform = $this->getEntityManager()->getConnection()->getDatabasePlatform();
    $rsm = new Query\ResultSetMapping();
    $rsm->addScalarResult($platform->getSQLResultCasing('dctrn_count'), 'count');
    $countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, CountOutputWalker::class);
    $countQuery->setResultSetMapping($rsm);

    return $countQuery->getSingleScalarResult(); //returns integer

【讨论】:

以上是关于Symfony2 Doctrine 错误:无法计算使用 HAVING 子句的查询。使用输出步行器进行分页的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 和 Doctrine - 错误:无效的 PathExpression。必须是 StateFieldPathExpression

在 Symfony2 中使用 Doctrine 映射异常错误

带有 Symfony2 的 Doctrine2 无法识别数据库字符集和排序规则

在 symfony2 和 Doctrine 应用程序中出现“列不能为空”错误

Symfony2 Doctrine2 获取所有表

Symfony2,Doctrine,fixtures,数组到字符串的转换