Подтвердить что ты не робот

Как я могу использовать SQL YEAR(), MONTH() и DAY() в Doctrine2?

Я хочу выполнить запрос, который будет выглядеть так в собственном SQL:

SELECT
    AVG(t.column) AS average_value
FROM
    table t
WHERE
    YEAR(t.timestamp) = 2013 AND
    MONTH(t.timestamp) = 09 AND
    DAY(t.timestamp) = 16 AND
    t.somethingelse LIKE 'somethingelse'
GROUP BY
    t.somethingelse;

Если я пытаюсь реализовать это в построителе запросов Doctrine следующим образом:

$qb = $this->getDoctrine()->createQueryBuilder();
$qb->select('e.column AS average_value')
   ->from('MyBundle:MyEntity', 'e')
   ->where('YEAR(e.timestamp) = 2013')
   ->andWhere('MONTH(e.timestamp) = 09')
   ->andWhere('DAY(e.timestamp) = 16')
   ->andWhere('u.somethingelse LIKE somethingelse')
   ->groupBy('somethingelse');

Я получаю исключение ошибки

[Синтаксическая ошибка] строка 0, col 63: Ошибка: ожидаемая известная функция, полученная 'YEAR'

Как я могу реализовать свой запрос с помощью конструктора запросов Doctrines?

Примечания:

  • Я знаю о Doctrine Native SQL. Я пробовал это, но это приводит к тому, что мои рабочие таблицы и базы данных моей разработки имеют разные имена. Я хочу работать с агностиком базы данных, поэтому это не вариант.
  • Хотя я хочу работать db agnostic: FYI, я использую MySQL.
  • Есть способ расширить Доктрину, чтобы "узнать" инструкции YEAR() и т.д., например. как здесь. Но я ищу способ избежать включения сторонних плагинов.
4b9b3361

Ответ 1

Вы можете добавить расширение Doctrine, чтобы вы могли использовать операторы MySql YEAR и MONTH, добавив эту конфигурацию, если вы используете Symfony:

doctrine:
    orm:
        dql:
            string_functions:
                MONTH: DoctrineExtensions\Query\Mysql\Month
                YEAR: DoctrineExtensions\Query\Mysql\Year

теперь вы можете использовать операторы MONTH и YEAR в своем DQL или построителе запросов.

Ответ 2

В Symfony 4 вы должны установить DoctrineExtensions:

composer require beberlei/DoctrineExtensions

А затем отредактируйте файл конфигурации doctrine (config/packages/doctrine.yaml) следующим образом:

doctrine:
    orm:
        dql:
            string_functions:
                MONTH: DoctrineExtensions\Query\Mysql\Month
                YEAR: DoctrineExtensions\Query\Mysql\Year

Ответ 3

orocrm/doctrine-extensions, кажется, тоже хороший проект

Он поддерживает как MySQL, так и PostgreSql. Цель состоит в том, чтобы быть cross DB

Ответ 4

Для Symfony 4:

  1. Установите: композитору требуются расширения beberlei/doctrine
  2. Изменить: config\packages\doctrine.yaml
    doctrine:
        orm:
            dql:
                datetime_functions:
                    DAY: DoctrineExtensions\Query\Mysql\Day
                    MONTH: DoctrineExtensions\Query\Mysql\Month
                    YEAR: DoctrineExtensions\Query\Mysql\Year
  1. Отредактируйте свой контроллер:
    public function somex()
    {
        $em = $this->getDoctrine()->getManager();

        $emConfig = $em->getConfiguration();
        $emConfig->addCustomDatetimeFunction('YEAR', 'DoctrineExtensions\Query\Mysql\Year');
        $emConfig->addCustomDatetimeFunction('MONTH', 'DoctrineExtensions\Query\Mysql\Month');
        $emConfig->addCustomDatetimeFunction('DAY', 'DoctrineExtensions\Query\Mysql\Day');

        $day = '22';
        $month = '4';

        $qb = $em->createQueryBuilder()
            ->select('u')
            ->from('App\Entity\User', 'u')
            ->where('DAY(u.somedate) = :day')
            ->andwhere('MONTH(u.somedate) = :month')
            ->setParameter('month', $day)
            ->setParameter('day', $month)
        ;
        $trab = $qb->getQuery()->getResult();


        return $this->render('intranet/somex.html.twig', [
            'trab' => $trab
        ]);
    }
    ''''