通过比较声明在Doctrine中排序结果

时间:2012-11-23 14:11:47

标签: php mysql orm doctrine-orm

摘要:我们可以在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方式。

2 个答案:

答案 0 :(得分:0)

尝试此查询

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;

答案 1 :(得分:0)

我的声誉不允许我对aykut的答案发表评论,但我只是想指出我与主题海报有完全相同的问题,CASE声明很好地解决了这个问题。

Kaivosukeltaja报告说使用CASE导致了一个Doctrine错误,但在我的情况下:-)这没有发生。从版本2.2开始,似乎已添加CaseExpressions: https://github.com/doctrine/doctrine2/commit/816ce41f638d28934c79a12ef27f954124b2639e