1. <legend id='f6CEz'><style id='f6CEz'><dir id='f6CEz'><q id='f6CEz'></q></dir></style></legend>

      <small id='f6CEz'></small><noframes id='f6CEz'>

        • <bdo id='f6CEz'></bdo><ul id='f6CEz'></ul>
        <tfoot id='f6CEz'></tfoot>
        <i id='f6CEz'><tr id='f6CEz'><dt id='f6CEz'><q id='f6CEz'><span id='f6CEz'><b id='f6CEz'><form id='f6CEz'><ins id='f6CEz'></ins><ul id='f6CEz'></ul><sub id='f6CEz'></sub></form><legend id='f6CEz'></legend><bdo id='f6CEz'><pre id='f6CEz'><center id='f6CEz'></center></pre></bdo></b><th id='f6CEz'></th></span></q></dt></tr></i><div id='f6CEz'><tfoot id='f6CEz'></tfoot><dl id='f6CEz'><fieldset id='f6CEz'></fieldset></dl></div>

        MySQL Tree 按父子顺序排序

        时间:2023-10-08
              • <bdo id='XyAQl'></bdo><ul id='XyAQl'></ul>

                <legend id='XyAQl'><style id='XyAQl'><dir id='XyAQl'><q id='XyAQl'></q></dir></style></legend>

                <tfoot id='XyAQl'></tfoot>

                  <small id='XyAQl'></small><noframes id='XyAQl'>

                1. <i id='XyAQl'><tr id='XyAQl'><dt id='XyAQl'><q id='XyAQl'><span id='XyAQl'><b id='XyAQl'><form id='XyAQl'><ins id='XyAQl'></ins><ul id='XyAQl'></ul><sub id='XyAQl'></sub></form><legend id='XyAQl'></legend><bdo id='XyAQl'><pre id='XyAQl'><center id='XyAQl'></center></pre></bdo></b><th id='XyAQl'></th></span></q></dt></tr></i><div id='XyAQl'><tfoot id='XyAQl'></tfoot><dl id='XyAQl'><fieldset id='XyAQl'></fieldset></dl></div>
                    <tbody id='XyAQl'></tbody>

                  本文介绍了MySQL Tree 按父子顺序排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在尝试使用此参考在 MYSQL 中显示树结构(http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/),我看到它只适用于同一个表中的 1 个父级.
                  如果你有另一张桌子要加入,一切都不会顺利.示例:

                  I'm trying to display a tree structure in MYSQL with this reference (http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/) and I'm seeing that only works with 1 parent in same table.
                  If you have another table to join with, nothing go well. Example:

                  餐桌菜单:

                  +----+--------+-------+
                  | id |  name  | order |
                  | 1  | Father |   0   |
                  | 2  | Father |   1   |
                  | 3  | Son    |   0   |
                  | 4  | Child  |   1   |
                  | 5  | Granson|   2   |
                  +----+--------+-------+
                  

                  表关系

                  +----+---------+-----------+
                  | id | menu_id | parent_id |
                  | 1  |    1    |    NULL   |
                  | 2  |    2    |    NULL   |
                  | 3  |    3    |     1     |
                  | 4  |    4    |     3     |
                  | 5  |    5    |     4     |
                  +----+---------+-----------+
                  

                  做选择

                  SELECT child_menu.*, menu.* FROM menu, relations AS child_menu
                  WHERE menu.id = child_menu.menu_id
                  GROUP BY menu_id
                  

                  我有这个:

                  +----+--------+-------+
                  | id |  name  | order |
                  | 1  | Father |   0   |
                  | 2  | Father |   1   |
                  | 3  | Son    |   0   |
                  | 4  | Child  |   1   |
                  | 5  | Granson|   2   |
                  +----+--------+-------+
                  

                  我试图在同一个 SELECT 中按顺序离开他们的孩子.
                  从我在示例中看到的情况来看,仅当父项在同一个表中时才有效.
                  有人能帮我吗?谢谢

                  I'm trying to leave their children in order in the same SELECT.
                  From what I see in the examples, only works if the parent is in the same table.
                  Can someone help me? thank you

                  预期输出:

                  +----+--------+-------+
                  | id |  name  | order |
                  | 1  | Father |   0   |
                  | 3  | Son    |   0   |
                  | 4  | Child  |   1   |
                  | 5  | Granson|   2   |
                  | 2  | Father |   1   |
                  +----+--------+-------+
                  
                  I.E. Father
                         Son
                           Child
                              Grandson
                  

                  推荐答案

                  除了 Mike Hillyer 的博客中显示的方法之外,还有其他方法可以组织分层数据.我喜欢使用一种我称之为传递闭包表或简称闭包表的方法.在此设计中,您将通过层次结构的每条路径都存储为祖先/后代对.

                  There are other ways to organize hierarchical data besides the methods shown in Mike Hillyer's blog. I like to use a method I call transitive closure table or closure table for short. In this design, you store every path through the hierarchy, as ancestor/descendant pairs.

                  create table closure (
                      ancestor int,
                      descendant int,
                      length int,
                      primary key (ancestor,descendant),
                      key (descendant,ancestor)
                  );
                  insert into closure values
                  (1,1,0),
                  (1,3,1),
                  (1,4,2),
                  (1,5,3),
                  (2,2,0),
                  (3,3,0),
                  (3,4,1),
                  (3,5,2),
                  (4,4,0),
                  (4,5,1),
                  (5,5,0);
                  

                  请注意,该集合甚至包括长度为零的路径",即菜单项是其自身的父项".

                  Note that this set includes even the "paths" of length zero, i.e. a menu item is an "parent" of itself.

                  现在您可以将每个菜单项 m 连接到它的每一个祖先 a 集合,方法是连接到 m 是后缀的路径.从那里,返回到祖先集合中的菜单项 o,您可以访问 order.

                  Now you can join each menu item m to every its set of ancestors a, by joining to paths where m is the descandant. From there, join back to the menu item o which is in the set of ancestors, and you can access the order.

                  使用 GROUP_CONCAT() 从祖先链中每个的 order 生成一串面包屑",这将成为一个字符串,您可以通过排序来获得所需的菜单顺序.

                  Use GROUP_CONCAT() to make a string of "breadcrumbs" from the order of each in the chain of ancestors, and this becomes a string you can sort by to get the menu order you want.

                  SELECT m.*, GROUP_CONCAT(o.`order` ORDER BY a.length DESC) AS breadcrumbs
                  FROM menu AS m
                  INNER JOIN closure AS a ON a.descendant = m.id
                  INNER JOIN menu AS o ON a.ancestor = o.id
                  GROUP BY m.id
                  ORDER BY breadcrumbs;
                  
                  +----+----------+-------+-------------+
                  | id | name     | order | breadcrumbs |
                  +----+----------+-------+-------------+
                  |  1 | Father1  |     0 | 0           |
                  |  3 | Son      |     0 | 0,0         |
                  |  4 | Child    |     1 | 0,0,1       |
                  |  5 | Grandson |     2 | 0,0,1,2     |
                  |  2 | Father2  |     1 | 1           |
                  +----+----------+-------+-------------+
                  

                  注意面包屑按字符串排序,所以如果你有一些order 2 或3 位数字,你会得到不规则的结果.确保您的 订单 编号都具有相同的位数.

                  Note that the breadcrumbs sort as a string, so if you have some order numbers with 2 or 3 digits, you will get irregular results. Make sure your order numbers all have the same number of digits.

                  或者,您可以简单地将面包屑字符串存储在原始菜单表中:

                  As an alternative, you could simply store the breadcrumbs strings in your original menu table:

                  ALTER TABLE menu ADD COLUMN breadcrumbs VARCHAR(255);
                  UPDATE menu SET breadcrumbs = '0,0,1,2' WHERE id = 5;
                  etc.
                  

                  然后你可以做一个更简单的查询:

                  Then you can do a simpler query:

                  SELECT * FROM menu ORDER BY breadcrumbs;
                  

                  但是,如果您更改菜单项的顺序,则由您手动重新计算所有受影响的面包屑字符串.

                  But then it's up to you to manually recalculate all affected breadcrumb strings, if you ever change the order of the menu items.

                  这篇关于MySQL Tree 按父子顺序排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:MySQL按最新评论或最后发布的帖子排序 下一篇:MySQL选择带有日期的行

                  相关文章

                2. <tfoot id='slpWE'></tfoot>
                    <bdo id='slpWE'></bdo><ul id='slpWE'></ul>

                  <small id='slpWE'></small><noframes id='slpWE'>

                    <legend id='slpWE'><style id='slpWE'><dir id='slpWE'><q id='slpWE'></q></dir></style></legend>

                    <i id='slpWE'><tr id='slpWE'><dt id='slpWE'><q id='slpWE'><span id='slpWE'><b id='slpWE'><form id='slpWE'><ins id='slpWE'></ins><ul id='slpWE'></ul><sub id='slpWE'></sub></form><legend id='slpWE'></legend><bdo id='slpWE'><pre id='slpWE'><center id='slpWE'></center></pre></bdo></b><th id='slpWE'></th></span></q></dt></tr></i><div id='slpWE'><tfoot id='slpWE'></tfoot><dl id='slpWE'><fieldset id='slpWE'></fieldset></dl></div>