我在表中有一个树结构,它使用物化路径让我快速找到孩子.但是,我也需要对结果进行深度优先排序,就像线程论坛回复一样.
id | parent_id | matpath | created ----+-----------+---------+---------------------------- 2 | 1 | 1 | 2010-05-08 15:18:37.987544 3 | 1 | 1 | 2010-05-08 17:38:14.125377 4 | 1 | 1 | 2010-05-08 17:38:57.26743 5 | 1 | 1 | 2010-05-08 17:43:28.211708 7 | 1 | 1 | 2010-05-08 18:18:11.849735 6 | 2 | 1.2 | 2010-05-08 17:50:43.288759 9 | 5 | 1.5 | 2010-05-09 14:02:43.818646 8 | 6 | 1.2.6 | 2010-05-09 14:01:17.632695
所以最终的结果实际上应该是这样排序的:
id | parent_id | matpath | created ----+-----------+---------+---------------------------- 2 | 1 | 1 | 2010-05-08 15:18:37.987544 6 | 2 | 1.2 | 2010-05-08 17:50:43.288759 8 | 6 | 1.2.6 | 2010-05-09 14:01:17.632695 3 | 1 | 1 | 2010-05-08 17:38:14.125377 4 | 1 | 1 | 2010-05-08 17:38:57.26743 5 | 1 | 1 | 2010-05-08 17:43:28.211708 9 | 5 | 1.5 | 2010-05-09 14:02:43.818646 7 | 1 | 1 | 2010-05-08 18:18:11.849735
我该怎么办?我可以在直sql(这是Postgresql 8.4)中执行此操作,还是应该将其他信息添加到此表中?
更新:试图更好地解释排序标准.
想象一下,id’1’是论坛的根帖,所有以’1’开头的’matpath’都是该帖子的小孩.所以ids 2到5是直接回复1并获得’1’的路径.然而,id 6是一个回复2,而不是直接到1,所以它得到一个1.2的matpath.这意味着对于具有正确嵌套的线程论坛,使用表中所示的所有ID,论坛的结构将如下所示,因此排序要求:
* id 1 (root post) * id 2 * id 6 * id 8 * id 3 * id 4 * id 5 * id 9 * id 7
解决方法
我通常为此创建一个额外的列,称为SortPath.它将包含您需要排序的数据,并排连接在一起.该列将为varchar类型,并将其作为字符串进行排序.这样的事情
id | parent_id | matpath | created | sortpath ---+-----------+---------+-----------------------------+-------------------------------------------------------------------------------------- 2 | 1 | 1 | 2010-05-08 15:18:37.987544 | 2010-05-08 15:18:37.987544-2 6 | 2 | 1.2 | 2010-05-08 17:50:43.288759 | 2010-05-08 15:18:37.987544-2.2010-05-08 17:50:43.288759-6 8 | 6 | 1.2.6 | 2010-05-09 14:01:17.632695 | 2010-05-08 15:18:37.987544-2.2010-05-08 17:50:43.288759-6.2010-05-09 14:01:17.632695-8 3 | 1 | 1 | 2010-05-08 17:38:14.125377 | 2010-05-08 17:38:14.125377-3 4 | 1 | 1 | 2010-05-08 17:38:57.26743 | 2010-05-08 17:38:57.267430-4 5 | 1 | 1 | 2010-05-08 17:43:28.211708 | 2010-05-08 17:43:28.211708-5 9 | 5 | 1.5 | 2010-05-09 14:02:43.818646 | 2010-05-08 17:43:28.211708-5.2010-05-09 14:02:43.818646-9 7 | 1 | 1 | 2010-05-08 18:18:11.849735 | 2010-05-08 18:18:11.849735-7
这里需要注意的几件事情:
> sortpath将被排序为一个字符串,所以重要的是所有日期都有相同的长度来正确排序.例如,观察如何在排序路径列中添加一个额外的零点:2010-05-08 17:38:57.26743.>我已经将每个节点的PK附加到其日期结束.这样做,如果你碰巧有两行完全相同的日期,它们将总是以相同的顺序返回,因为我们附加的附加数据.对我来说,数据看起来是不对称的,因为我们在sortpath中显示了当前节点的日期,但并不在matpath中.我宁愿在两者中看到它.>您可能希望将节点ID 1的日期放在每个排序列的开头.这样,如果你想要一次查询多个论坛(你可能不会),那么它仍然会排序正确.