用Doctrine按多列排序


115

我需要按两列排序数据(当行的第1列具有不同的值时,按此排序;否则按第2列进行排序)

我正在使用QueryBuilder创建查询。

如果我orderBy第二次调用该方法,它将替换以前指定的任何顺序。

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

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

但是我不能为第二个参数传递两个排序方向,因此当我执行此查询时,第一列按升序排序,第二列按降序排序。我想对它们两个都使用降序。

有没有办法做到这一点QueryBuilder?我需要使用DQL吗?

Answers:


213

您必须在列名称后添加订单方向:

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

如前所述,多个调用orderBy 不会叠加,但是您可以对进行多次调用addOrderBy

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

2
谢谢。我以前没有注意到这一点。我以为有两个ord​​erBy语句可以。所以我没有意识到addOrderBy方法。为指出而欢呼:)

DiegoAgulló:不幸的是,答案中的两个链接都不再起作用。
k00ni

1
@ k00ni感谢您指出这一点。我将前者更新为最新文档,但在GitHub上找不到已迁移的问题DC-909,因此我删除了后者。
迭戈·阿古洛

对于具有表别名的查询构建器,请不要忘记添加alias.column_name
Maulik Parmar

16

在Doctrine 2.x中,您不能使用上面示例中的教义“ orderBy”或“ addOrderBy”传递多个订单。因为,当您将第二个参数保留为空白时(例如在“ orderBy”函数中),它会自动在最后一列名称的末尾添加“ ASC”。

例如,->orderBy('a.fist_name ASC, a.last_name ASC')将输出类似“ ORDER BY first_name ASC,last_name ASC ASC”的SQL。因此,这是SQL语法错误。仅仅是因为orderBy或addOrderBy的默认值为'ASC'。

要添加多个订单,您需要使用“添加”功能。它将是这样。

->add('orderBy','first_name ASC, last_name ASC')。这将为您提供正确格式的SQL。

有关add()函数的更多信息。https://www.doctrine-project.org/projects/doctrine-orm/zh/2.6/reference/query-builder.html#low-level-api

希望这可以帮助。干杯!


8

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

添加:Doctrine Querybuilder btw。经常使用的常规方法“特殊”的修改,见select-addSelectwhere-andWhere-orWheregroupBy-addgroupBy...


0

对于注释orderBy的源代码注释:Keys are field and values are the order, being either ASC or DESC.。这样就可以了orderBy->(['field' => Criteria::ASC])


这是不正确的。请参阅上面的答案
Thomas Hansen

0

orderBy方法需要两个字符串或一个Expr\OrderBy对象。如果要添加多个订单声明,则正确的addOrderBy方法是使用method或实例化一个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)
   ;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.