Maison >base de données >tutoriel mysql >Comment récupérer la ligne maximale ou la dernière par groupe à l'aide du langage de requête Doctrine (DQL) ?
Langage de requête de doctrine : Récupération du maximum ou de la dernière ligne par groupe
Afin de récupérer le maximum ou la dernière ligne pour chaque groupe à l'aide du Doctrine Query Language (DQL), il est nécessaire de tirer parti des sous-requêtes pour identifier les lignes cibles. Les étapes suivantes expliquent comment y parvenir :
Requête SQL originale :
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
Équivalent au langage de requête Doctrine :
Premier Tentative :
$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 :
[Erreur sémantique] ligne 0, col 73 près de 'ShmupBundle:Score' : Erreur : la classe ShmupBundleEntityScore n'a pas association nommée nom
Corrigé Version :
$kb = $em->createQuery( "SELECT a FROM ShmupBundle:Score a INNER JOIN ShmupBundle:Score b WITH a.score = b.score AND a.name = b.name GROUP BY a.name WHERE a.platform='keyboard' GROUP BY a.name ORDER BY b.score DESC, a.dateCreated DESC" );
Explication :
Dans la requête SQL d'origine, une sous-requête est utilisée pour calculer le score maximum pour chaque nom. Ce résultat est ensuite joint à la requête principale pour identifier les lignes avec les scores les plus élevés.
Pour traduire cela en DQL, une approche similaire est nécessaire. Cependant, le champ a.name n'existe pas en tant qu'association dans l'entité Score (comme l'indique le message d'erreur). Pour résoudre ce problème, la sous-requête est écrite sous la forme d'une jointure d'entité distincte, à la condition que a.score et b.score soient égaux et que a.name et b.name soient égaux.
Une alternative à cette approche consiste à réviser la requête SQL pour utiliser la fonction ROW_NUMBER(), qui peut fournir les mêmes résultats sans avoir besoin d'une sous-requête. Le DQL utilisé pour cette méthode dépend de la version de Doctrine utilisée. Par exemple :
use Doctrine\ORM\Query\Expr\Func; $query = $em->createQuery( 'SELECT a FROM Score AS a WHERE FUNC("ROW_NUMBER()", a.name) = 1 ORDER BY a.score DESC' );
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!