我不确定MySQL是否可以做到这一点,但让我们尝试一下。
像这样的表中有几行
UID - Name - Generation - ParentUID
1 - Parent1 - 1 - 0
3 - Parent2 - 1 - 0
7 - Parent4 - 1 - 0
14 - Child7 - 2 - 3
17 - Child8 - 2 - 3
20 - Parent8 - 1 - 0
55 - Child9 - 2 - 7
75 - Child12 - 3 - 55
90 - Child40 - 3 - 17
95 - Child20 - 2 - 7
,依此类推... 现在,我想以这种方式进行排序。如果ParentUID不为0,则将自己置于父级下方。
在这种情况下,应该是:
UID - Name - Generation - ParentUID
1 - Parent1 - 1 - 0
3 - Parent2 - 1 - 0
14 - Child7 - 2 - 3
17 - Child8 - 2 - 3
90 - Child40 - 3 - 17
7 - Parent4 - 1 - 0
55 - Child9 - 2 - 7
75 - Child12 - 3 - 55
95 - Child20 - 2 - 7
20 - Parent8 - 1 - 0
Child20在Child12之后,因为Child9是Child12的父母。您可以说它看起来像一个文件夹结构。 不仅持续了三代,而且持续了五,七代。这是否可能,或者我应该获取所有数据,然后使用一些PHP魔术对其进行排序?
答案 0 :(得分:1)
您要首先对记录深度进行排序,从左到右。一种常见的方法是遍历树以构建一个表示元素路径的排序列。在MySQL 8.0中,您可以使用递归cte来做到这一点:
with recursive cte(uid, name, generation, parent_uid, path) as (
select t.*, cast(lpad(uid, 3, 0) as char(100)) from mytable t where parent_uid = 0
union all
select t.*, concat(c.path, '/', lpad(t.uid, 3, 0))
from cte c
inner join mytable t on t.parent_uid = c.uid
)
select * from cte order by path
uid | name | generation | parent_uid | path --: | :------ | ---------: | ---------: | :---------- 1 | Parent1 | 1 | 0 | 001 3 | Parent2 | 1 | 0 | 003 14 | Child7 | 2 | 3 | 003/014 17 | Child8 | 2 | 3 | 003/017 90 | Child40 | 3 | 17 | 003/017/090 7 | Parent4 | 1 | 0 | 007 55 | Child9 | 2 | 7 | 007/055 75 | Child12 | 3 | 55 | 007/055/075 95 | Child20 | 2 | 7 | 007/095 20 | Parent8 | 1 | 0 | 020