[英]Symfony/Doctrine get entries count by day on a datetime field
假设我们有一个 Symfony 实体,包含一个id
(int)、 title
(string) 和created
(datetime) 字段。
我现在需要按天数,比如
day, amount
2015-11-22, 5
2015-11-23, 2
2015-11-24, 0
目前我只是加载所有条目(当前月份),在 PHP 中循环它们并在提交的日期时间调用format('Ym-d')
以获取日期,然后我将该日期存储在包含该日期的数组中键和数量作为值(如果日期在数组中,只需增加 1,否则将值设置为 1)。
必须有更好的方法,我很确定,我应该能够直接在数据库上计算它。
使用普通的 sql 我会做类似的事情
SELECT DATE(created) AS day, COUNT(DISTINCT id) AS amount
FROM testtable
GROUP BY DATE(created)
编辑:由于查询将在主键 id 上使用COUNT()
,并且通过该唯一键,这里不需要COUNT(DISTINCT id)
,因此COUNT(id)
将产生完全相同的结果。 但是,如果我要对标题进行计数并且我只想计算唯一标题,那么它需要COUNT()
的DISTINCT
关键字,就像有人想知道一样。
但是我怎么能用 Symfony/Doctrine 做到这一点呢?
我已经找到了一个解决方案,希望这可以帮助遇到类似问题的其他人。
首先, Doctrine
没有Date
函数,因为并非所有 DB 系统都支持Date
。 Doctrine 的构建是为了能够与所有主要的数据库系统一起工作,所以这里没有原生的Date
。
要为 MySQL 添加日期函数(不确定其他数据库),我们可以创建一个新类,我们称之为DQLDate
。 我的看起来像这样:
<?php
namespace Foo\BarBundle\DQL;
use \Doctrine\ORM\Query\AST\Functions\FunctionNode,
\Doctrine\ORM\Query\SqlWalker,
\Doctrine\ORM\Query\Parser,
\Doctrine\ORM\Query\Lexer;
/**
* Extracts the date form a timestamp (Mysql function)
* DQLDate :: DATE ( date as Y-m-d )
*/
class DQLDate extends FunctionNode
{
protected $date;
public function getSql(SqlWalker $sqlWalker)
{
return 'DATE(' . $sqlWalker->walkArithmeticPrimary($this->date) .')';
}
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->date = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
接下来我们需要在我们的config.yml
文件中注册该函数。
# Doctrine Configuration
doctrine:
...
orm:
...
dql:
datetime_functions:
DATE: Foo\BarBundle\DQL\DQLDate
然后我们都准备好了。
如果我们假设 SQL 查询
SELECT DATE(created) AS day, COUNT(DISTINCT id) AS amount
FROM testtable
GROUP BY DATE(created)
我们现在可以将其转换为
$q = $this->getEntityManager()->createQueryBuilder()
->select('DATE(e.created) AS day, COUNT(DISTINCT e.id) AS amount')
->from('FooBarBundle:TestTable', 'e')
->groupBy('day');
$result = $q->getQuery()->getResult();
如问题中所述,如果字段是唯一的,则不需要COUNT
的DISTINCT
关键字。 例如,如果我们要计算标题,并且想知道有多少不同的标题,那么我们需要DISTINCT
关键字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.