Mysql
 sql >> Base de données >  >> RDS >> Mysql

Doctrine Query Language obtient le maximum/la dernière ligne par groupe

La requête que vous essayez de faire avec la doctrine est liée à . Utiliser une sous-requête puis se joindre à la requête principale rend les choses compliquées à gérer avec la doctrine. Voici donc la version SQL réécrite pour obtenir les mêmes résultats sans utiliser de fonctions d'agrégation :

SELECT 
  a.* 
FROM
  score a 
  LEFT JOIN score b 
    ON a.name = b.name 
    AND a.score < b.score 
WHERE b.score IS NULL 
ORDER BY a.score DESC 

DÉMO

Pour convertir la requête ci-dessus équivalente en doctrine ou DQL est facile, ci-dessous est la version DQL de SQL ci-dessus :

SELECT a 
FROM AppBundle\Entity\Score a
    LEFT JOIN AppBundle\Entity\Score b 
    WITH a.name = b.name 
    AND a.score < b.score
WHERE b.score IS NULL
ORDER BY a.score DESC

Ou avec le générateur de requêtes, vous pouvez écrire quelque chose comme j'ai testé ci-dessous avec symfony 2.8 en utilisant le Schéma DEMO

$DM   = $this->get( 'Doctrine' )->getManager();
$repo = $DM->getRepository( 'AppBundle\Entity\Score' );
$results = $repo->createQueryBuilder( 'a' )
                ->select( 'a' )
                ->leftJoin(
                    'AppBundle\Entity\Score',
                    'b',
                    'WITH',
                    'a.name = b.name AND a.score < b.score'
                )
                ->where( 'b.score IS NULL' )
                ->orderBy( 'a.score','DESC' )
                ->getQuery()
                ->getResult();

Une autre idée serait de créer une vue en utilisant votre requête dans la base de données et dans symfony de créer une entité, de mettre le nom de la vue dans l'annotation de la table et de commencer à appeler votre entité, elle donnera les résultats renvoyés par votre requête, mais cette approche n'est pas recommandée. juste un correctif temporaire .