Trier par plusieurs colonnes avec Doctrine

115

J'ai besoin de classer les données par deux colonnes (lorsque les lignes ont des valeurs différentes pour la colonne numéro 1, triez-les; sinon, triez par colonne numéro 2)

J'utilise un QueryBuilderpour créer la requête.

Si j'appelle la orderByméthode une deuxième fois, elle remplace tous les ordres spécifiés précédemment.

Je peux passer deux colonnes comme premier paramètre:

->orderBy('r.firstColumn, r.secondColumn', 'DESC');

Mais je ne peux pas passer deux directions de classement pour le deuxième paramètre, donc lorsque j'exécute cette requête, la première colonne est ordonnée dans une direction ascendante et la seconde, décroissante. Je voudrais utiliser la descente pour les deux.

Y a-t-il un moyen de faire cela en utilisant QueryBuilder? Dois-je utiliser DQL?

zootropo
la source

Réponses:

213

Vous devez ajouter le sens de la commande juste après le nom de la colonne:

$qb->orderBy('column1 ASC, column2 DESC');

Comme vous l'avez noté, plusieurs appels à orderBy ne pas empiler , mais vous pouvez effectuer plusieurs appels à addOrderBy:

$qb->addOrderBy('column1', 'ASC')
   ->addOrderBy('column2', 'DESC');
Diego Agulló
la source
2
Merci. je n'ai pas remarqué cela avant. Je pensais que deux déclarations orderBy étaient correctes pour cela. donc je n'ai pas réalisé la méthode addOrderBy. bravo pour l'avoir signalé :)
Diego Agulló: Malheureusement, les deux liens de votre réponse ne fonctionnent plus.
k00ni
1
@ k00ni merci d'avoir signalé cela. J'ai mis à jour le premier avec les derniers documents, mais je n'ai pas trouvé le problème migré DC-909 sur GitHub, j'ai donc supprimé le dernier.
Diego Agulló
Pour les générateurs de requêtes avec alias de table, n'oubliez pas d'ajouter alias.column_name.
Maulik Parmar
16

Dans Doctrine 2.x, vous ne pouvez pas passer des ordres multiples en utilisant la doctrine 'orderBy' ou 'addOrderBy' comme dans les exemples ci-dessus. Parce que, il ajoute automatiquement le «ASC» à la fin du nom de la dernière colonne lorsque vous avez laissé le second paramètre vide, comme dans la fonction «orderBy».

Pour un exemple ->orderBy('a.fist_name ASC, a.last_name ASC'), affichera SQL quelque chose comme ceci 'ORDER BY first_name ASC, last_name ASC ASC'. Il s'agit donc d'une erreur de syntaxe SQL. Simplement parce que la valeur par défaut de orderBy ou addOrderBy est «ASC».

Pour ajouter plusieurs commandes, vous devez utiliser la fonction «ajouter». Et ce sera comme ça.

->add('orderBy','first_name ASC, last_name ASC'). Cela vous donnera le SQL correctement formaté.

Plus d'informations sur la fonction add (). https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html#low-level-api

J'espère que cela t'aides. À votre santé!

Anjana Silva
la source
8

vous pouvez utiliser ->addOrderBy($sort, $order)

Ajouter: Doctrine Querybuilder btw. utilise souvent des modifications de « spéciales » des méthodes normales, voir select-addSelect, where-andWhere-orWhere, groupBy-addgroupBy...

Christian Huber
la source
0

Le commentaire des orderBynotes de code source: Keys are field and values are the order, being either ASC or DESC.. Alors vous pouvez le faire orderBy->(['field' => Criteria::ASC]).

Victor S
la source
Ce n'est pas correct. Voir ma réponse ci
Thomas Hansen le
0

La orderByméthode nécessite soit deux chaînes, soit un Expr\OrderByobjet. Si vous souhaitez ajouter plusieurs déclarations d'ordre, la bonne chose est d'utiliser une addOrderByméthode ou d'instancier un OrderByobjet et de le remplir en conséquence:

   # Inside a Repository method:
   $myResults = $this->createQueryBuilder('a')
       ->addOrderBy('a.column1', 'ASC')
       ->addOrderBy('a.column2', 'ASC')
       ->addOrderBy('a.column3', 'DESC')
   ;

   # Or, using a OrderBy object:
   $orderBy = new OrderBy('a.column1', 'ASC');
   $orderBy->add('a.column2', 'ASC');
   $orderBy->add('a.column3', 'DESC');

   $myResults = $this->createQueryBuilder('a')
       ->orderBy($orderBy)
   ;
Thomas Hansen
la source