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) ?

Comment récupérer la ligne maximale ou la dernière par groupe à l'aide du langage de requête Doctrine (DQL) ?

DDD
DDDoriginal
2024-11-18 22:32:02478parcourir

How to Retrieve the Maximum or Latest Row Per Group Using Doctrine Query Language (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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn