Symfony项目中如何用Doctrine实现指定GROUP BY COUNT查询?
解决Symfony中Doctrine实现指定分组统计查询的问题
首先,你的原始SQL是要统计documents_lignes表中每个idJeu对应的记录数,按数量倒序取前20条。结合documents_lignes与boite表通过idJeu(对应boite.id)关联的关系,以下是正确的Doctrine实现方案:
正确的QueryBuilder实现
public function findBoitesGroupeBy() { return $this->createQueryBuilder('dl') ->select('b.id as idJeu, COUNT(dl.id) as total') ->innerJoin('dl.boite', 'b') ->groupBy('b.id') ->orderBy('total', 'DESC') ->setMaxResults(20) ->getQuery() ->getArrayResult(); }
代码说明:
select('b.id as idJeu, COUNT(dl.id) as total'):对应原始SQL的SELECT idJeu, COUNT(*),用b.id对应原表的idJeu字段,COUNT(dl.id)替代COUNT(*)(效果一致,更符合Doctrine规范),给统计数起别名total方便后续排序。innerJoin('dl.boite', 'b'):关联boite表,需确保DocumentsLignes实体中已正确配置boite关联属性。groupBy('b.id'):对应原始SQL的GROUP BY idJeu,b.id就是关联的idJeu字段。orderBy('total', 'DESC'):实现原始SQL的ORDER BY count(*) DESC排序规则。setMaxResults(20):对应原始SQL的LIMIT 20,限制返回结果数量。getArrayResult():返回数组格式结果,也可根据需求改用getResult()获取实体对象数组。
你原有代码的问题点
- 选择字段错误:
select('dl.boite, COUNT(dl.boite)')中dl.boite是关联的Boite实体对象,并非原始SQL所需的idJeu字段,导致返回结果不符合预期。 - 缺少排序和限制:未添加
orderBy和setMaxResults,无法实现倒序和取前20条的逻辑。 - 统计字段选择:
COUNT(dl.boite)虽能统计关联存在的记录数,但COUNT(dl.id)更直观,可避免关联对象带来的潜在问题。
可选:DQL实现方式
若你更习惯使用DQL,可采用以下写法:
public function findBoitesGroupeBy() { $dql = 'SELECT b.id as idJeu, COUNT(dl.id) as total FROM App\Entity\DocumentsLignes dl INNER JOIN dl.boite b GROUP BY b.id ORDER BY total DESC'; return $this->getEntityManager() ->createQuery($dql) ->setMaxResults(20) ->getArrayResult(); }
注意:需确保
DocumentsLignes实体中boite关联属性的映射正确,示例如下:// 在DocumentsLignes实体中 /** * @ORM\ManyToOne(targetEntity=Boite::class) * @ORM\JoinColumn(name="idJeu", referencedColumnName="id") */ private $boite;
内容的提问来源于stack exchange,提问作者Je-Développe
相关产品推荐
相关产品推荐

