web-dev-qa-db-fra.com

Comment puis-je utiliser SQL YEAR (), MONTH () et DAY () dans Doctrine2?

Je veux effectuer une requête qui ressemblerait à ceci en SQL natif:

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;

Si j'essaie d'implémenter cela dans le générateur de requêtes de Doctrine comme ceci:

$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');

Je reçois l'exception d'erreur

[Erreur de syntaxe] ligne 0, col 63: Erreur: fonction connue attendue, obtenu 'ANNÉE'

Comment puis-je implémenter ma requête avec le générateur de requêtes Doctrines?

Remarques:

  • Je connais SQL natif de Doctrine . J'ai essayé cela, mais cela conduit au problème que mes tables de base de données de production et de développement ont des noms différents. Je veux travailler indépendamment de la base de données, ce n'est donc pas une option.
  • Bien que je veuille travailler avec agnostic db: FYI, j'utilise MySQL.
  • Il y a moyen d'étendre Doctrine pour "apprendre" les instructions YEAR() etc., par exemple comme vu ici . Mais je cherche un moyen pour éviter d'inclure des plugins tiers.
27

Vous pouvez ajouter extension Doctrine pour pouvoir utiliser les instructions MySql YEAR et MONTH en ajoutant cette configuration si vous êtes sur Symfony:

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

vous pouvez maintenant utiliser les instructions MONTH et YEAR dans votre DQL ou votre constructeur de requêtes.

36
alex88

Dans Symfony 4 vous devez installer DoctrineExtensions :

composer require beberlei/DoctrineExtensions

Et puis éditez le fichier de configuration doctrine (config/packages/doctrine.yaml) comme suit:

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

orocrm/doctrine-extensions semble aussi être un bon projet

Il prend en charge à la fois MySQL et PostgreSql .. le but est d'être cross DB

2
drAlberT