Doctrine 2:按字段别名分组(错误:'...'不指向类。)

时间:2010-10-22 08:54:05

标签: php doctrine-orm

我得到了这个Doctrine查询:

        select upper(substring(e.name, 1, 1)) first_letter
        from Application\Models\Exercise e
        group by first_letter
        order by first_letter asc

但是它会抛出一条消息:

Error: 'first_letter' does not point to a Class. 

如果我遗漏了group byorder by,它就可以了。

在这种情况下我是否必须使用本机查询,或者在我的客户端代码中进行排序和分组(可能不是一个好主意,具体取决于数据库中的数据量......)或者是否可以获取这个查询有效吗?

谢谢!


编辑:

这是我目前的方法,不太好,但目前正在工作,因为数据库中没有太多数据:

    $tmpResult = $this->getEntityManager()->createQuery('
        select upper(substring(e.name, 1, 1)) first_letter
        from Application\Models\Exercise e
    ')->getResult();

    $groupedAndSortedResult = array();

    foreach($tmpResult as $row) {
        $groupedAndSortedResult[$row['first_letter']] = $row['first_letter'];
    }

    sort($groupedAndSortedResult);

    return array_values($groupedAndSortedResult);

3 个答案:

答案 0 :(得分:2)

我知道您自己已经回答了这个问题,但只是想知道您是否尝试使用DISTINCT

select DISTINCT upper(substring(e.name, 1, 1)) first_letter
from Application\Models\Exercise e    
order by e.name asc

在这种情况下,按e.name排序相当于first_letter

答案 1 :(得分:1)

似乎没有好办法通过DQL(至少没有我能找到的)这样做,因为Doctrine总是试图将结果映射到实体。我最终使用PDO连接进行本机查询。这是我在我的存储库中使用的代码:

    return $this->getEntityManager()->getConnection()->executeQuery('
        select upper(left(tl_exercise.name, 1)) as first_letter
        from tl_exercise
        group by first_letter
        order by first_letter asc
    ')->fetchAll(\PDO::FETCH_COLUMN);

至少我摆脱了客户端代码中的排序/分组。我可以使用默认情况下LEFT()中未提供的DQL函数(但您可以使用SUBSTRING())。


更新:有一种方法可以使用EntityManager::createQueryDQL完成此操作,请参阅rojoca´s answer

答案 2 :(得分:0)

我的猜测是它正在寻找first_letter成为一个实体。在一些SQL查询中,这是类似的问题,您不能将select语句中的计算属性用作条件。请尝试以下方法:

select upper(substring(e.name, 1, 1)) first_letter
from Application\Models\Exercise e
group by upper(substring(e.name, 1, 1))
order by upper(substring(e.name, 1, 1)) asc