通过比较语句对 Doctrine 中的结果进行排序

Posted

技术标签:

【中文标题】通过比较语句对 Doctrine 中的结果进行排序【英文标题】:Ordering results in Doctrine by comparison statement 【发布时间】:2012-11-23 14:11:47 【问题描述】:

总结:我们可以在 Doctrine 中做ORDER BY parent_id = id DESC 吗?

我们有一个数据库表Category,其中包含分层文章类别。表格如下所示:

CREATE TABLE IF NOT EXISTS `Category` (
  `id` int(11) NOT NULL auto_increment,
  `parent_id` int(11) default NULL,
  `name` varchar(255) collate utf8_unicode_ci NOT NULL,
  `sort` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `IDX_FF3A7B97727ACA70` (`parent_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=22 ;

层次结构只有一层深,最高层的parent_idid相同。

我们希望使用 Doctrine QueryBuilder 获取所有行(DQL 也可以),以便连续列出所有类别,类别的父类别是第一个,子类别紧随其后。像这样:

id  parent_id   sort    name
-----------------------------------
1   1           1       Animals
5   1           1       Cat
10  1           3       Dog
9   1           2       Walrus
2   2           2       Fruits
13  2           3       Apple
12  2           2       Pear
11  2           1       Melon
3   3           3       Vehicles
15  3           2       Car
6   3           3       Train
14  3           1       Paraglider

使用这个原生 mysql 查询,我们可以按照我们想要的顺序获取项目:

select * from Category order by parent_id asc, parent_id = id desc;

但是,我们不知道如何在 QueryBuilder 或 DQL 中执行此操作。问题是 parent_id = id 排序条件导致 DQL 出现错误:[Syntax Error] line 0, col 109: Error: Expected end of string, got '='

我们有一个使用 $em->createNativeQuery() 的解决方法,但我们真的很想找到一种合适的方法来以 ORM 方式执行此操作。

【问题讨论】:

【参考方案1】:

试试这个查询

SELECT *, CASE id WHEN parent_id THEN 1 ELSE 0 END AS custom_order
FROM Category 
WHERE ORDER BY parent_id ASC, custom_order DESC;

【讨论】:

谢谢,但我需要问题中显示的顺序中的所有行。没有WHERE,查询可以正常工作,并产生我们想要的结果。我们只想在没有原生 MySQL 查询的情况下做到这一点。 除了id等于parent_id的行之外,你想获取所有行吗? 是的,我们需要它们主要由parent_id 排序,其次是它们的parent_id 是否与它们的id 相同。 谢谢,但我需要把它翻译成 DQL。使用 CASE 会导致 Doctrine 错误(“预期文字,得到 CASE”)。 现在我无法尝试使用 DQL 进行查询,但我认为它可以使用 createNativeQuery() 方法。【参考方案2】:

我的名声不允许我对aykut 的回答发表评论,但我只想指出,我遇到了与主题海报完全相同的问题,CASE 声明很好地解决了它。

Kaivosukeltaja 报告说使用 CASE 会导致 Doctrine 错误,但在我的情况下 :-) 这并没有发生。似乎 CaseExpressions 自 2.2 版以来已添加: https://github.com/doctrine/doctrine2/commit/816ce41f638d28934c79a12ef27f954124b2639e

【讨论】:

以上是关于通过比较语句对 Doctrine 中的结果进行排序的主要内容,如果未能解决你的问题,请参考以下文章

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

Linux——MySQL高阶语句杂而精

Linux——MySQL高阶语句杂而精

使用Doctrine phpcr-odm对sort_order排序结果

在SELECT语句中,对查询结果进行排序的子句是啥?能消除重复行的关键字是啥?

是否可以在 Doctrine 2 ODM 中的多个字段上使用 sort()?