Ordena por varias columnas con Doctrine

115

Necesito ordenar los datos por dos columnas (cuando las filas tienen diferentes valores para la columna número 1, ordene por ella; de lo contrario, ordene por la columna número 2)

Estoy usando QueryBuilderpara crear la consulta.

Si llamo al orderBymétodo por segunda vez, reemplaza cualquier orden especificado previamente.

Puedo pasar dos columnas como primer parámetro:

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

Pero no puedo pasar dos direcciones de orden para el segundo parámetro, por lo que cuando ejecuto esta consulta, la primera columna se ordena en dirección ascendente y la segunda, descendente. Me gustaría usar descendente para ambos.

¿Hay alguna forma de hacer esto usando QueryBuilder? ¿Necesito usar DQL?

zootropo
fuente

Respuestas:

213

Debe agregar la dirección del pedido justo después del nombre de la columna:

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

Como ha observado, varias llamadas orderBy no se acumulan , pero puede realizar varias llamadas a addOrderBy:

$qb->addOrderBy('column1', 'ASC')
   ->addOrderBy('column2', 'DESC');
Diego Agulló
fuente
2
Gracias. No me di cuenta de esto antes. Pensé que dos declaraciones orderBy están bien para esto. así que no me di cuenta del método addOrderBy. aplausos para señalarlo :)
Diego Agulló: Lamentablemente, ambos enlaces de su respuesta ya no funcionan.
k00ni
1
@ k00ni gracias por señalar esto. Actualicé el primero a los documentos más recientes, pero no pude encontrar el problema migrado DC-909 en GitHub, así que eliminé el último.
Diego Agulló
Para los constructores de consultas con alias de tabla, no olvide agregar alias.column_name.
Maulik Parmar
16

En Doctrine 2.x no puedes pasar varios pedidos usando la doctrina 'orderBy' o 'addOrderBy' como en los ejemplos anteriores. Porque agrega automáticamente el 'ASC' al final del nombre de la última columna cuando dejó el segundo parámetro en blanco, como en la función 'orderBy'.

Por ejemplo ->orderBy('a.fist_name ASC, a.last_name ASC'), SQL generará algo como esto 'ORDER BY first_name ASC, last_name ASC ASC'. Así que este es un error de sintaxis SQL. Simplemente porque el valor predeterminado de orderBy o addOrderBy es 'ASC'.

Para agregar varios pedidos, debe usar la función 'agregar'. Y será así.

->add('orderBy','first_name ASC, last_name ASC'). Esto le dará el SQL con el formato correcto.

Más información sobre la función add (). https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html#low-level-api

Espero que esto ayude. ¡Salud!

Anjana Silva
fuente
8

puedes usar ->addOrderBy($sort, $order)

Agregar: Doctrine Querybuilder por cierto. utiliza a menudo modificaciones "especiales" de los métodos normales, ver select-addSelect, where-andWhere-orWhere, groupBy-addgroupBy...

Christian Huber
fuente
0

El comentario de orderBynotas de código fuente: Keys are field and values are the order, being either ASC or DESC.. Entonces puedes hacerlo orderBy->(['field' => Criteria::ASC]).

Víctor S
fuente
Esto no es correcto. Vea mi respuesta arriba
Thomas Hansen
0

El orderBymétodo requiere dos cadenas o un Expr\OrderByobjeto. Si desea agregar varias declaraciones de pedido, lo correcto es usar el addOrderBymétodo o crear una instancia de un OrderByobjeto y completarlo en consecuencia:

   # 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
fuente