我在Item
和Valoracion
之间有一个简单的双向一对多关系(评论)。以下查询应按降序获取每个商品的平均分数和评论数:
$itemsQb = $em->getRepository(Item::class)->createQueryBuilder('i')
->select('i as data')
->addSelect('avg(v.score) as avg_score')
->addSelect('count(v.score) as num_reviews')
->leftJoin('i.valoraciones', 'v')
->groupBy('i.id')
->addOrderBy('avg_score', 'DESC')
->addOrderBy('num_reviews', 'DESC');
其中$em
是有效的Doctrine\ORM\EntityManager
实例。当使用Doctrine\ORM\Tools\Pagination\Paginator
对上述查询进行分页并使用getIterator()
遍历结果时,将引发异常,如下所示:
$pag = new Paginator($itemsQb);
// first page, up to three results per page
$pag->getQuery()->setFirstResult(0)->setMaxResults(3);
// display results one by one
echo "Name\t\tAvg\tNum\n";
foreach ($pag->getIterator() as $p) {
echo $p['data']->name . "\t" . $p['avg_score'] . "\t" . $p['num_reviews'] . "\n";
}
SQLSTATE [42000]:语法错误或访问冲突:1055 SELECT列表的表达式#5不在GROUP BY子句中,并且包含未聚合的列'test.v1_.score',该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by
不兼容
已生成以下SQL查询
SELECT DISTINCT
id_5
FROM
(SELECT DISTINCT
id_5, sclr_2, sclr_3
FROM
(SELECT
i0_.id AS id_0,
i0_.name AS name_1,
AVG(v1_.score) AS sclr_2,
COUNT(v1_.score) AS sclr_3,
v1_.score AS score_4,
i0_.id AS id_5
FROM
item i0_
LEFT JOIN valoracion v1_ ON i0_.id = v1_.item_id
GROUP BY i0_.id) dctrn_result_inner
ORDER BY sclr_2 DESC , sclr_3 DESC) dctrn_result
LIMIT 3
很明显,v1_.score AS score_4,
行根本不应该在那儿!
那么,为什么会生成此无效的SQL?我在做错什么吗?
注释:
getQuery()->getResult()
代替getIterator()
,则一切正常。我仍然在寻求帮助,因为当getIterator()
传递到模板时,Twig 显然在for
循环后使用$pag
。ORDER BY
子句,一切也将正常工作!sql_mode=ONLY_FULL_GROUP_BY
,但我不想更改它。答案 0 :(得分:0)
在这种情况下,您无需获取已加入的“ to-many collection”,而是按商品ID 分组,而仅汇总“ valoraciones ”关系的值
根据doctrine pagination documentation,在这种情况下,您可以 禁用$ fetchJoinCollection标志 :
$pag = new Paginator($itemsQb, false);
问题似乎是由教义试图将按条件排列的“缺失字段”添加到选择子句中引起的。 Related issue Pull request
在这种情况下,它认为应该在选择项上添加“ v.score”。
或者,您可以在分页器中禁用输出步进器,以避免出现上述现象:
$pag->setUseOutputWalkers(false);