使用 Doctrine 按多列排序

Posted

技术标签:

【中文标题】使用 Doctrine 按多列排序【英文标题】:Order by multiple columns with Doctrine 【发布时间】:2012-07-19 11:49:25 【问题描述】:

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

我使用QueryBuilder 来创建查询。

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

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

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

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

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

【问题讨论】:

【参考方案1】:

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

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

如您所述,多次调用orderBydo not stack,但您可以多次调用addOrderBy

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

【讨论】:

谢谢。我以前没有注意到这一点。我认为这两个 orderBy 语句是可以的。所以我没有意识到 addOrderBy 方法。为指出这一点而欢呼:) Diego Agulló:不幸的是,您的答案中的两个链接都不再起作用了。 @k00ni 感谢您指出这一点。我将前者更新为最新的文档,但在 GitHub 上找不到迁移的问题 DC-909,所以我删除了后者。 对于具有表别名的查询构建器,不要忘记添加alias.column_name【参考方案2】:

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

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

【讨论】:

【参考方案3】:

在 Doctrine 2.x 中,您不能使用上述示例中的教义 '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('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

希望这会有所帮助。干杯!

【讨论】:

【参考方案4】:

orderBy源代码注释的注释:Keys are field and values are the order, being either ASC or DESC.。所以你可以做orderBy->(['field' => Criteria::ASC])

【讨论】:

【参考方案5】:

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)
   ;

【讨论】:

【参考方案6】:

您可以使用 orderBy() 后跟 addOrderBy() - 嵌套多个 orderBy() 是不可能的,但在初始 orderBy() 之后嵌套多个 addOrderBy() 也可以。

例子:

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

【讨论】:

以上是关于使用 Doctrine 按多列排序的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine 可以处理多列 UNIQUE 索引吗?

在 Doctrine2 DQL 查询上进行排序的 CASTING 属性

如何在 Doctrine 中使用 findBy() 对结果进行排序

如何使用 Doctrine 更改列字符集和排序规则?

在 Symfony 中防止 Doctrine 的查询缓存

如何对 findAll Doctrine 的方法进行排序?