我刚刚开始研究Symfony 3.4和Doctrine ORM。我需要统计用户数。我测试了正常的查询,它工作正常。如何将普通查询转换为Doctrine ORM?任何帮助,将不胜感激。
"SELECT count(DATE_FORMAT(application.reviewed_at, '%Y-%m-%d')) AS count, user_id FROM application WHERE user_id = 6 AND DATE(reviewed_at) = CURDATE() GROUP BY DATE(reviewed_at)";
我尝试了以下代码。它不起作用。
$qb = $em->createQueryBuilder();
$entries = $qb->select("count(DATE_FORMAT(application.reviewed_at, '%Y-%m-%d')) AS count", "user_id")
->where("user_id = 6", "DATE(reviewed_at) = CURDATE()")
->from('AppBundle\Entity\Application', 'u');
->groupBy("DATE(reviewed_at)");
->getQuery()
->getResult();
答案 0 :(得分:2)
简而言之,Doctrine ORM并非旨在将SQL查询转换回DQL。 DQL是一种查询语言,可以转换为多个特定于供应商的SQL变体,因此这是从DQL到SQL的单向转换。
因此,如果您只有一个SQL查询,那么最好仅使用using Doctrine DBAL。当然,您可能必须处理结果集映射,但是可能无需将所有ORM内容拖到您的代码中。
您在这里所做的本质上是使用Doctrine的QueryBuilder
API构建DQL查询。 FROM
部分是绝对正确的,但是使用DATE_FORMAT
和DATE
函数的用户对我来说似乎是错误的。由于DQL转换为几种不同的SQL实现,具体取决于您使用的驱动程序,因此它需要一个兼容性层,因为DATE_FORMAT
,DATE
和CURDATE
之类的功能并不是所有平台。
首先,看看documentation for user-defined functions。例如,MySQL中的DATEDIFF()
函数就是一个很好的例子。如果事实证明还没有人实现对您正在使用的功能的支持,那么这是一个不错的起点,因为它基本上描述了如何实现对教义查询语言(DQL)的扩展。
第二,很有可能您正在使用的功能已经在某些第三方库中实现,例如OroCRM's或Benjamin Eberlei's Doctrine扩展集合。
此外,如果您要选择一个聚合或函数调用结果,最好给它加上别名。您可以在这里尝试使用$qb->expr()
函数子集将DQL限制为更严格的语法。
答案 1 :(得分:0)
请务必记住,Doctrine DQL是不是 SQL方言。这是一种自定义语言,试图看起来与SQL相似,但是它使用Doctrine实体和关联而不是数据库表和列进行操作。当然,最后它会转换为SQL,但是在进行此转换之前,您需要保持DQL语法不变。
查询不起作用的原因之一是尝试在DQL查询中使用本机SQL(实际上是MySQL)功能。 DQL没有此类功能,此时您有2种方法:
reviewet_at
列从现在(我想是timestamp
)转换为允许直接进行日期比较的date
类型。它将使您摆脱自定义MySQL日期转换功能,并使查询与Doctrine兼容答案 2 :(得分:0)
尝试尝试一下:
public function select()
{
$queryBuilder = $this->createQueryBuilder('a');
$queryBuilder
->addSelect(['a.user_id', $queryBuilder->expr()->count('a.reviewed_at')])
->where('a.user_id = :idUser')
->andWhere('a.reviewed_at = :date')
->setParameters([
'idUser' => 6,
'date' => new \DateTime(),
])
->groupBy('a.reviewed_at')
;
return $queryBuilder
->getQuery()
->getResult()
;
}