Ordene por múltiplas colunas com o Doctrine

115

Preciso ordenar os dados por duas colunas (quando as linhas têm valores diferentes para a coluna número 1, ordenar por ela; caso contrário, ordenar pela coluna número 2)

Estou usando um QueryBuilderpara criar a consulta.

Se eu chamar o orderBymétodo uma segunda vez, ele substituirá todas as ordens especificadas anteriormente.

Posso passar duas colunas como o primeiro parâmetro:

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

Mas não posso passar duas direções de ordenação para o segundo parâmetro, portanto, quando executo esta consulta, a primeira coluna é ordenada em uma direção crescente e a segunda, em ordem decrescente. Eu gostaria de usar a descida para os dois.

Existe uma maneira de fazer isso usando QueryBuilder? Eu preciso usar DQL?

zootropo
fonte

Respostas:

213

Você deve adicionar a direção do pedido logo após o nome da coluna:

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

Como você observou, várias chamadas para orderBy não empilhar , mas você pode fazer várias chamadas para addOrderBy:

$qb->addOrderBy('column1', 'ASC')
   ->addOrderBy('column2', 'DESC');
Diego agulló
fonte
2
obrigado. Eu não percebi isso antes. Achei que duas declarações orderBy fossem adequadas para isso. então eu não percebi o método addOrderBy. aplausos por apontar isso :)
Diego Agulló: Infelizmente ambos os links em sua resposta não estão mais funcionando.
k00ni
1
@ k00ni obrigado por apontar isso. Atualizei o primeiro para os documentos mais recentes, mas não consegui encontrar o problema migrado DC-909 no GitHub, então removi o último.
Diego Agulló
Para construtores de consulta com alias de tabela, não se esqueça de adicionar alias.column_name.
Maulik Parmar
16

No Doctrine 2.x você não pode passar pedidos múltiplos usando a doutrina 'orderBy' ou 'addOrderBy' como os exemplos acima. Porque, ele adiciona automaticamente o 'ASC' no final do nome da última coluna quando você deixou o segundo parâmetro em branco, como na função 'orderBy'.

Para um exemplo ->orderBy('a.fist_name ASC, a.last_name ASC'), o SQL irá gerar algo como 'ORDER BY first_name ASC, last_name ASC ASC'. Portanto, este é um erro de sintaxe SQL. Simplesmente porque o padrão de orderBy ou addOrderBy é 'ASC'.

Para adicionar vários pedidos por, você precisa usar a função 'adicionar'. E vai ser assim.

->add('orderBy','first_name ASC, last_name ASC'). Isso lhe dará o SQL formatado corretamente.

Mais informações sobre a função add (). https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html#low-level-api

Espero que isto ajude. Felicidades!

Anjana Silva
fonte
8

você pode usar ->addOrderBy($sort, $order)

Adicionar: Doctrine Querybuilder btw. muitas vezes usa modificações "especiais" dos métodos normais, veja select-addSelect, where-andWhere-orWhere, groupBy-addgroupBy...

Christian Huber
fonte
0

O comentário de orderBynotas de código fonte: Keys are field and values are the order, being either ASC or DESC.. Então você pode fazer orderBy->(['field' => Criteria::ASC]).

Victor S
fonte
Isso não está correto. Veja minha resposta acima
Thomas Hansen
0

O orderBymétodo requer duas strings ou um Expr\OrderByobjeto. Se você deseja adicionar várias declarações de pedido, o correto é usar o addOrderBymétodo ou instanciar um OrderByobjeto e preenchê-lo de acordo:

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