Problème :
Traduction d'une instruction SQL en langage de requête Doctrine (DQL) pour récupérer la ligne maximale ou la dernière pour chaque groupe.
SQL Déclaration :
SELECT a.* FROM score a INNER JOIN ( SELECT name, MAX(score) AS highest FROM score GROUP BY name ) b ON a.score = b.highest AND a.name = b.name GROUP BY name ORDER BY b.highest DESC, a.dateCreated DESC
Tentative DQL :
$kb = $em->createQuery( "SELECT a FROM ShmupBundle:Score a INNER JOIN a.name ShmupBundle:Score b WITH a.score = b.score AND a.name = b.name GROUP BY b.name WHERE a.platform='keyboard' GROUP BY a.name ORDER BY b.score DESC, a.dateCreated DESC" );
Erreur :
[Semantical Error] line 0, col 73 near 'ShmupBundle:Score': Error: Class ShmupBundle\Entity\Score has no association named name
Solution :
La tentative DQL tente de utilisez une association nommée « nom », qui n'existe pas dans l'entité Score.
Instruction SQL réécrite :
Pour éviter d'utiliser des fonctions d'agrégation, l'instruction SQL peut être réécrit comme :
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
Équivalent DQL :
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
Version du générateur de requêtes :
À l'aide du générateur de requêtes, la requête peut être écrite comme :
$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();
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!