与父母和孩子对行进行排序

时间:2020-03-31 07:35:51

标签: php mysql

我不确定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魔术对其进行排序?

1 个答案:

答案 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

Demo on DB Fiddle

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        
相关问题