首页 > 解决方案 > 使用父母和孩子对行进行排序

问题描述

我不确定这是否可以使用 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 魔法对其进行排序?

标签: phpmysql

解决方案


您想首先对记录深度进行排序,从左到右。一种常见的方法是遍历树以构建表示元素路径的排序列。在 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

DB Fiddle 上的演示

uid | 姓名 | 一代| parent_uid | 小路       
--: | :-------- | ---------: | ---------: | :----------
  1 | 家长1 | 1 | 0 | 001        
  3 | 家长2 | 1 | 0 | 003        
 14 | 儿童7 | 2 | 3 | 003/014    
 17 | 儿童8 | 2 | 3 | 003/017    
 90 | 儿童40 | 3 | 17 | 003/017/090
  7 | 家长4 | 1 | 0 | 007        
 55 | 孩子9 | 2 | 7 | 007/055    
 75 | 儿童12 | 3 | 55 | 007/055/075
 95 | 儿童20 | 2 | 7 | 007/095    
 20 | 家长8 | 1 | 0 | 020        

推荐阅读