GroupBy DAY using Doctrine2

天涯浪子 提交于 2019-12-13 02:23:49

问题


I am looking for way to group my policies by day. I was trying a lot of examples how to do this but still there are some errors. Can anyone help me with this? Here I will show only two examples, others i was trying were similar to those. Differences were only in used SQL's functions ex(CAST, SUBSTRING, DATE...) First way i was trying is:

$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() returns:

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)

and the error is:

[Semantical Error] line 0, col 156 near 'DAY(p.transa': Error: Cannot group by undefined identification or result variable.

And the second way is:

$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() returns:

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)

and the error is:

[Semantical Error] line 0, col 72 near 'FROM GLPolicyBundle:Policy': Error: Class 'FROM' is not defined.


回答1:


Doctrine doesn't support many of the native db functions because it is supposed to work with many different types of databases. So you're left with three options.

  1. Use the NativeQuery class (http://docs.doctrine-project.org/en/latest/reference/native-sql.html)
  2. Implement a custom SQL walker. Here is an example for grouping by day (https://github.com/beberlei/DoctrineExtensions/blob/master/lib/DoctrineExtensions/Query/Mysql/Day.php)
  3. Install a bundle that adds the grouping methods for you https://github.com/beberlei/DoctrineExtensions



回答2:


For those who want to use the DQL, there is a way to do it:

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

See the doc for SUBSTRING

SUBSTRING(str,pos,len). The forms with a len argument return a substring len characters long from string str, starting at position pos.

In my example, i start at position 1 to 10 which gives me YYYY-MM-DD. For instance, if you just want the day, you can start at position 9 with a length of 2

SUBSTRING(p.transactionDate, 9, 2)


来源:https://stackoverflow.com/questions/17702674/groupby-day-using-doctrine2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!