我正在尝试使用doctrine创建一个查询,它基本上应该在SQL中看起来像这样:
SELECT p.* FROM some_tabel AS p GROUP BY p.type;
所以我最终得到了这个,因为这是我最接近的记录:
private function getAll()
{
//$this->em => Entity Manager
return $this->em->createQueryBuilder()
->select('p')
->from('AppBundle:Robots', 'p')
->groupBy('p.type')
->getQuery()
->getResult(Query::HYDRATE_ARRAY);
}
错误告诉我'p.type'未被选中。
我怎样才能让它发挥作用?
更新
正如@Felippe Duarte的公认答案中所提到的,似乎Mysql的分组是一种有线的。即使我跑:
SELECT p.*, max(p.id) FROM some_tabel AS p GROUP BY p.type;
正如许多答案所建议的那样,结果并不是我所期望的,因为只包含每种类型的第一项而且没有真正的分组。
订购而不是分组的选项很好,但仍然会给我留下一些处理,所以在这种情况下它是多余的。
最后,这段代码可以满足我的需求:
private function groupByType(array $robots)
{
return array_reduce($robots,
function($list, $robot)
{
$list[$robot->getType()][] = $robot;
return $list;
}, []);
}
因为这不是太多代码而且不会太多»机器人«我决定 - 遵循KISS范式 - 这是首选的解决方案。
答案 0 :(得分:2)
您不能按单列分组,也可以选择其他列。 MySQL有这个“错误”,允许用户在选择多列时按一列分组。
换句话说,您必须group by
所有未使用聚合函数的列,如SUM,AVG,MAX,COUNT。
MySQL的这个“特性”的副作用是返回其他列的第一个结果,即使它不代表真相。
试试这个脚本:
create table test(id int, name char(1), value1 int);
insert into test values(1, 'a', 1);
insert into test values(2, 'b', 1);
select name, value1, max(id) from test group by value1;
“预期”输出
name: 'b', value1: 1, max(id): 2
实际输出:
name: 'a', value1: 1, max(id): 2
答案 1 :(得分:2)
您是否尝试过这样的“createQuery”:
return $this->em->createQuery(
'SELECT p.* FROM some_tabel AS p GROUP BY p.type'
)->getQuery()->getResult(Query::HYDRATE_ARRAY);
看看是否有效? 如果没有运行,请尝试删除“Query :: HYDRATE_ARRAY”。
答案 2 :(得分:0)
您需要一些聚合,例如计算每种类型的条目:
private function getAll()
{
//$this->em => Entity Manager
return $this->em->createQueryBuilder()
->select('p.type, count(*)')
->from('AppBundle:Robots', 'p')
->groupBy('p.type')
->getQuery()
->getResult(Query::HYDRATE_ARRAY);
}
答案 3 :(得分:0)
以下是类似情况下对我有用的内容:
<?php
$conn = $this->getDoctrine()->getEntityManager()->getConnection();
$dql = $conn->createQueryBuilder();
$dql->select("p")
->from('AppBundle:Robots', 'p')
->groupBy('p.type');
$qr = $em->createQuery($dql);
$result = $qr->getResult(AbstractQuery::HYDRATE_ARRAY);
答案 4 :(得分:0)
关于这个问题的答案似乎没有帮助并重新阅读你的问题的标题,我想你认为排序数据而不是 分组。
然后使用ORDER BY p.type
代替。在Doctrine中,这可以这样做:
->orderBy('p.type', 'ASC')