使用Doctrine2进行GroupBy DAY

时间:2013-07-17 14:34:31

标签: symfony doctrine-orm group-by

我正在寻找按日分组政策的方法。我尝试了很多例子如何做到这一点,但仍有一些错误。谁能帮我这个? 在这里,我将只展示两个例子,其他我正在尝试的类似于那些。区别仅在于使用过的SQL函数ex(CAST,SUBSTRING,DATE ...) 我尝试的第一种方式是:

$query =  $this->getEntityManager()
                        ->createQueryBuilder();   
$query->select('count(p), p.transactionDate')
                        ->from('GLPolicyBundle:Policy', 'p')
                        ->andwhere('p.shop IN (:shop_id)')
                        ->setParameter('shop_id', $shop_list)
                        ->andWhere($query->expr()->between('p.transactionDate', ':date_from', ':date_to'))
                        ->setParameter('date_from', $date_from, \Doctrine\DBAL\Types\Type::DATETIME)
                        ->setParameter('date_to', $date_to, \Doctrine\DBAL\Types\Type::DATETIME)
                        ->addGroupBy('DAY(p.transactionDate)');

getDQL()返回:

SELECT count(p), p.transactionDate FROM GLPolicyBundle:Policy p 
WHERE p.shop IN (:shop_id) AND (p.transactionDate BETWEEN :date_from AND :date_to) 
GROUP BY DAY(p.transactionDate)

,错误是:

  

[语义错误]第0行,col 156靠近'DAY(p.transa':错误:不能   未定义的标识或结果变量分组。

第二种方式是:

$query = $this->getEntityManager()
            ->createQuery("SELECT p,  (p.transactionDate) AS group
                            FROM GLPolicyBundle:Policy p
                            WHERE p.shop IN (:shop_id) AND (p.transactionDate BETWEEN :date_from AND :date_to) 
                            GROUP BY DAY(group)")
                            ->setParameter('shop_id', $shop_list)
                            ->setParameter('date_from', $date_from, \Doctrine\DBAL\Types\Type::DATETIME)
                            ->setParameter('date_to', $date_to, \Doctrine\DBAL\Types\Type::DATETIME);

getDQL()返回:

SELECT p, (p.transactionDate) AS group FROM GLPolicyBundle:Policy p 
WHERE p.shop IN (:shop_id) AND (p.transactionDate BETWEEN :date_from AND :date_to) 
GROUP BY DAY(group)

,错误是:

  

[语义错误]第0行,第72页'FROM GLPolicyBundle:Policy'附近:   错误:未定义类“FROM”。

2 个答案:

答案 0 :(得分:3)

Doctrine不支持许多本机数据库功能,因为它应该适用于许多不同类型的数据库。所以你有三个选择。

  1. 使用NativeQuery班级(http://docs.doctrine-project.org/en/latest/reference/native-sql.html
  2. 实现自定义SQL walker。以下是按日分组的示例(https://github.com/beberlei/DoctrineExtensions/blob/master/lib/DoctrineExtensions/Query/Mysql/Day.php
  3. 安装捆绑包,为您添加分组方法https://github.com/beberlei/DoctrineExtensions

答案 1 :(得分:1)

对于那些想要使用DQL的人来说,有一种方法可以做到:

$query->select('count(p), p.transactionDate, SUBSTRING(p.transactionDate, 1, 10) as my_date')
    //...
    ->groupBy('my_date');

请参阅SUBSTRING

的文档
  

SUBSTRING(STR,POS,LEN)。带有len参数的表单从字符串str返回一个子字符串len个字符,从位置pos开始。

在我的例子中,我从1到10的位置开始,它给了我YYYY-MM-DD。例如,如果您只想要这一天,则可以从位置9开始,长度为2

SUBSTRING(p.transactionDate, 9, 2)