使用Doctrine按多列排序

135

我需要按照两列数据排序(当行的第一列具有不同值时,以它为准进行排序;否则,以第二列为准进行排序)

我正在使用QueryBuilder创建查询。

如果我第二次调用orderBy方法,它会替换掉之前指定的任何排序。

我可以将两个列作为第一个参数传递:

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

但是我无法为第二个参数传递两个排序方向,所以当我执行这个查询时,第一列按升序排序,第二列按降序排序。我想让它们都按降序排序。

是否有一种方法可以使用 QueryBuilder 实现这一点?我需要使用 DQL 吗?

6个回答

273

您需要在列名后立即添加排序方向:

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

正如您所指出的,多次调用 orderBy 不能叠加,但是您可以多次调用 addOrderBy

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

3
谢谢。我之前没有注意到这一点。我以为两个orderBy语句对这个问题没问题,所以我没有意识到addOrderBy方法。感谢你指出来 :) - user3676604
1
Diego Agulló:很不幸,你回答中的两个链接都已经失效了。 - k00ni
1
@k00ni 感谢您指出这一点。我已将前者更新为最新文档,但我在 GitHub 上找不到已迁移的问题 DC-909,因此我将其删除了。 - Diego Agulló
对于带有表别名的查询构建器,请不要忘记添加 alias.column_name - Maulik Parmar

21
在Doctrine 2.x中,您无法使用Doctrine的'orderBy'或'addOrderBy'传递多个排序方式,就像上面的示例一样。因为当您将第二个参数留空时,它会自动在最后一列名称的末尾添加'ASC',例如在'orderBy'函数中。
例如:->orderBy('a.fist_name ASC, a.last_name ASC')将输出类似于“ORDER BY first_name ASC, last_name ASC ASC”的SQL。这是SQL语法错误,仅仅是因为orderBy或addOrderBy的默认值是“ASC”。
要添加多重排序,请使用'add'函数。应该如下所示: ->add('orderBy','first_name ASC, last_name ASC')。这将为您提供正确格式的SQL。
有关add()函数的更多信息,请参见https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html#low-level-api 希望这可以帮助您。干杯!

11

您可以使用->addOrderBy($sort, $order)

补充说明:Doctrine Querybuilder通常会使用“特殊”的修改方式来修改普通方法,例如select-addSelectwhere-andWhere-orWheregroupBy-addgroupBy等。


10

您可以使用orderBy()后跟一个addOrderBy() - 无法嵌套多个orderBy(),但是在初始orderBy()之后嵌套多个addOrderBy()也可行。

例子:

$this->createQueryBuilder('entity')
       ->orderBy('entity.addDate', 'DESC')
       ->addOrderBy('entity.id', 'DESC')
  

1
orderBy方法需要两个字符串或一个Expr\OrderBy对象。如果您想添加多个排序声明,则正确的方法是使用addOrderBy方法,或实例化一个OrderBy对象并相应地填充它:
   # 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)
   ;

非常好的答案。我只想说:这是Doctrine让你的生活变得如此轻松的那些情况之一,它真的很难。 :-) - David

0
< p > orderBy 源代码的注释说明:键是字段,值是顺序,可以是ASC或DESC。。因此,您可以执行 orderBy-&gt;(['field' => Criteria :: ASC])


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接