Doctrine - 选择所有字段并按其中一个分组

时间:2016-05-25 16:42:22

标签: php doctrine-orm symfony

我正在尝试使用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范式 - 这是首选的解决方案。

5 个答案:

答案 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')