繁体   English   中英

Symfony/Doctrine 获取日期时间字段中按天计数的条目

[英]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();

如问题中所述,如果字段是唯一的,则不需要COUNTDISTINCT关键字。 例如,如果我们要计算标题,并且想知道有多少不同的标题,那么我们需要DISTINCT关键字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM