简体   繁体   中英

Sort rows with parents and children

I am not sure if this is possible with MySQL but let's give it a try.

There are a few rows in a table like this

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

and so on... Now I would like to sort it that way. If the ParentUID is not 0 place yourself below your parent.

So in that case it would be:

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 comes after Child12, because Child9 is the parent of Child12. You could say that it looks like a folder-structure. And not only for three but for five or seven generations. Is that possible or should I get all the data and then sort it with some PHP magic?

You want to sort records depth first, the left to right. A common approach is to traverse the tree to build a sorting column that represents the path to the element. In MySQL 8.0, you can do this with a recursive 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM