2012-04-03 92 views
2

我有一个模式,基本上是这样的:MySQL的层次分组排序

CREATE TABLE `data` (
    `id` int(10) unsigned NOT NULL, 
    `title` text, 
    `type` tinyint(4), 
    `parent` int(10) 
) 

type场仅仅是一个枚举,其中1是一个父类,和2个孩子的类型(实际上有许多类型,其中一些应该像父母一样行事,一些像孩子一样)。 parent字段表示一条记录是另一条记录的子节点。

我知道这可能不是我想要构建的查询的理想选择,但这是我必须使用的。

我想对数据进行排序和分组,以便父记录按title排序,并且在每个父代下分组是根据title排序的子记录。像这样:

ID | title  |type |parent 
-------------------------------- 
4 | ParentA  | 1 | 
2 | ChildA  | 2 | 4 
5 | ChildB  | 2 | 4 
7 | ParentB  | 1 | 
9 | ChildC  | 2 | 7 
1 | ChildD  | 2 | 7 

** 编辑 **

我们应该能够采取type场出来的图片完全。如果parent不为空,那么它应该被分组在它的父代下面。

+2

这是一个2级层次结构还是任意深度的树? – 2012-04-03 20:14:18

+0

@Eric,只是一个简单的2层次的层次结构 – ack 2012-04-03 20:16:14

回答

2
SELECT * FROM `data` ORDER BY COALESCE(`parent`, `id`), `parent`, `id` 
+0

这似乎很好,干净...我不认为通过'title'要求排序可以工作到ORDER BY子句中吗? – ack 2012-04-03 21:34:58

+0

得到这个工作,感谢领先! 'ORDER BY COALESCE(IF(parentID,parentTitle,NULL),IF(ID,title,NULL)),parentID,title' - 适用于我的实际查询,因为我有一个连接,它给了我'parentTitle',我可以然后在需要时换入COALESCE。 – ack 2012-04-03 22:17:57

+0

对不起,我没有注意到“标题”要求。 – Neil 2012-04-04 23:35:57

0

以下是经过测试可在SQL Server上运行的解决方案。应该是基本相同的关于MySQL

select Id, Title, [Type], Id as OrderId from Hier h1 where [Type] = 1 
union 
select Id, Title, [Type], Parent as OrderId from Hier h2 where [Type] = 2 
order by OrderId, [Type] 
0

你说你想它来排序的冠军,是否正确?

SELECT id, title, parent 
FROM 
    (SELECT id, title, parent, 
    CASE WHEN parent is null THEN title ELSE CONCAT((SELECT title FROM `data` d2 WHERE d2.id = d.parent), '.', d.title) END AS sortkey 
    FROM `data` d 
    ) subtable 
ORDER BY sortkey 

修改:编辑删除查询中的type

+0

对结果进行字符串连接和排序效率相当低。 – 2012-04-03 22:05:29