我得到了这个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 by
和order 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);
答案 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::createQuery
和DQL
完成此操作,请参阅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