Как я могу использовать 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()
и т.д., например. как здесь. Но я ищу способ избежать включения сторонних плагинов.
Ответы
Ответ 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:
- Установите: композитору требуются расширения beberlei/doctrine
- Изменить: config\packages\doctrine.yaml
doctrine:
orm:
dql:
datetime_functions:
DAY: DoctrineExtensions\Query\Mysql\Day
MONTH: DoctrineExtensions\Query\Mysql\Month
YEAR: DoctrineExtensions\Query\Mysql\Year
- Отредактируйте свой контроллер:
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
]);
}
''''