简体   繁体   English

父子mysql

[英]Parent child mysql

Say I have a table like this: 说我有这样一张桌子:

=================================
| ID |  Parent_ID | Page_Name   |
=================================
| 1  |  NULL      |  Home       |
| 2  |  NULL      |  Services   |
| 3  |  2         |  Baking     |
| 4  |  3         |  Cakes      |
| 5  |  3         |  Bread      |
| 6  |  5         |  Flat Bread |
---------------------------------

How can I go about actually ordering the results in this format? 如何以这种格式实际订购结果? Ie Ordered by the Parent -> Child -> Sub Child, on the basis I would only ever require say a maximum of 5 levels? 即由父母 - >儿童 - >子儿童订购,在此基础上我只需要说最多5个等级? I have looked into the "Nested Set Model" but it seems too complex for my requirements. 我已经研究过“嵌套集模型”,但对我的要求来说似乎太复杂了。 What I am unsure about is really understanding a SQL query I can use to display my results like above, or in this situation should I be using a server side language like PHP to do this for me? 我不确定的是真正理解我可以用来显示我的结果的SQL查询,或者在这种情况下,我应该使用像PHP这样的服务器端语言为我做这个吗?

EDIT 编辑

working sample addressing Gordons note 工作样本解决戈登的注意事项

Query calculate node path as you have fixed maximum tree depth, and order by it. 查询计算节点路径,因为您已经修复了最大树深度,并按此顺序排序。

SQL Fiddle SQL小提琴

MySQL 5.5.30 Schema Setup : MySQL 5.5.30架构设置

create table mytable(id int, parent_id int, name varchar(100));

insert mytable(id, parent_id, name)
values (1, null, 'Home'),
(2, null, 'Services'),
(3, 2, 'Baking'),
(4, 3, 'Cakes'),
(5, 3, 'Bread'),
(6, 5, 'Flat Bread'),
(7, 1, 'Something');

Query 1 : 查询1

select t0.*,
  concat(
      case coalesce(t4.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t4.Parent_ID as char), '\\')
      end,
      case coalesce(t3.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t3.Parent_ID as char), '\\')
      end,
      case coalesce(t2.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t2.Parent_ID as char), '\\')
      end,
      case coalesce(t1.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t1.Parent_ID as char), '\\')
      end,
      case coalesce(t0.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t0.Parent_ID as char), '\\')
      end,
      cast(t0.id as char)
    ) as path
from mytable t0 
    left join mytable t1 on t0.Parent_ID = t1.Id
    left join mytable t2 on t1.Parent_ID = t2.Id
    left join mytable t3 on t2.Parent_ID = t3.Id
    left join mytable t4 on t3.Parent_ID = t4.Id
order by 
  concat(
      case coalesce(t4.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t4.Parent_ID as char), '\\')
      end,
      case coalesce(t3.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t3.Parent_ID as char), '\\')
      end,
      case coalesce(t2.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t2.Parent_ID as char), '\\')
      end,
      case coalesce(t1.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t1.Parent_ID as char), '\\')
      end,
      case coalesce(t0.Parent_ID, 0) 
        when 0 then ''
        else concat(cast(t0.Parent_ID as char), '\\')
      end,
      cast(t0.id as char)
    )

Results : 结果

| ID | PARENT_ID |       NAME |    PATH |
-----------------------------------------
|  1 |    (null) |       Home |       1 |
|  7 |         1 |  Something |     1\7 |
|  2 |    (null) |   Services |       2 |
|  3 |         2 |     Baking |     2\3 |
|  4 |         3 |      Cakes |   2\3\4 |
|  5 |         3 |      Bread |   2\3\5 |
|  6 |         5 | Flat Bread | 2\3\5\6 |

You can try this: 你可以试试这个:

select t.*,
       (case when t4.parent_id is not NULL then 5
             when t4.id is not null then 4
             when t3.id is not null then 3
             when t2.id is not null then 2
             when t1.id is not null then 1
             else 0
        end) as level
from t left outer join
     t t1
     on t.parent_id = t1.id left outer join
     t t2
     on t1.parent_id = t2.id left outer join
     t t3
     on t2.parent_id = t3.id left outer join
     t t4
     on t3.parent_id = t4.id
order by coalesce(t4.parent_id, t4.id, t3.id, t2.id, t1.id, t.id),
         coalesce(t4.id, t3.id, t2.id, t1.id, t.id),
         coalesce(t3.id, t2.id, t1.id, t.id),
         coalesce(t1.id, t.id),
         t.id

Recursive queries are not needed if the hierarchy is finite. 如果层次结构是有限的,则不需要递归查询。

The order by clause is the tricky part. order by子句是棘手的部分。 It just orders by the levels of the hierarchy, starting at the topmost level. 它只是按层次结构的级别排序,从最顶层开始。

The original version of this worked on the data in the question. 这个版本的原始版本适用于问题中的数据。 More extensive testing found that it did not always work. 更广泛的测试发现它并不总是有效。 I believe this version always works. 我相信这个版本总能奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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