【问题标题】:how to create tree view in mysql using stored procedure如何使用存储过程在mysql中创建树视图
【发布时间】:2016-05-16 09:24:25
【问题描述】:

我很困惑。我不知道如何使用存储过程在 MySQL 中创建树视图。我尝试在 Google 中搜索,但我不明白如何查询。

我有

deptid  |  dept_code |  dept_name  | parent_deptid
     1             1    wadir Umum           0
     2           101   bagian umum           1
     3         10101   kepala umum           2
     4           102   bagian privasi        1
     5       1010101   SUb bagian Tu         3
     6       1010102   bagian umum           3

我想变成这样

deptid  |  dept_code |  dept_name  |    parent_deptid
     1             1   wadir Umum                0
     2           101   -bagian umum              1
     3         10101   --kepala umum             2
     5       1010101   ---Sub bagian Tu          3 
     6       1010102   ---bagian umum            3
     4           102   -bagian privasi           1

【问题讨论】:

  • 数据的结构是什么?您的查询是什么?
  • 当 parentid 为 3 时,为什么 deptid=5 排在 deptid=6 之后?
  • 对不起我的错误编辑

标签: php mysql stored-procedures tree materialized-path-pattern


【解决方案1】:

由于部门代码模式看起来很方便,所以我没有花时间在 parent_id 上。根据您的部门代码模式,以下应该会有所帮助。

只需填充部门代码并获取可排序的统一代码。

请在查询中更改您的表名。

SELECT * 
FROM tableName
ORDER BY RPAD(dept_code, 5, '0')

编辑:实际上,如果 parent_deptid 是实际父母的 id,那么您只需要按 parent_deptid 排序,然后是 dept_code。但是,parent_deptid 看起来不像对应的父级 id,而是类似于“深度”。

EDIT2:抱歉,您的 parent_deptid 看起来没问题,只是需要查看更多显示其他父 ID 的数据。所以我错过了。所有你需要排序如下:

SELECT * 
FROM tableName
ORDER BY parent_deptid, dept_code;

EDIT3 - 根据已编辑的问题:通过更改填充字符串长度回到我最初的建议 - 以下是最适合您的数据结构的解决方案。

SELECT * 
FROM tableName
ORDER BY RPAD(dept_code, 10, '0')
  • 10 可能是您的 dept_code 的最大长度。

【讨论】:

  • @HardianZ 我最初的回答应该有所帮助,但需要根据您的新样本数据更改填充长度。请尝试一下。
【解决方案2】:

将您的 dept_code 列类型更改为 VARCHAR 并使用下一个查询

SELECT * 
FROM tableName
ORDER BY dept_code

【讨论】:

    【解决方案3】:

    以下查询将创建标记输出:

    SELECT group_concat(
      CONCAT(
        REPEAT('    ', (CHAR_LENGTH(t.dept_code) - 1) / 2),
        '- ',
        t.dept_name
      )
      ORDER BY t.dept_code
      SEPARATOR '\n'
    ) AS markup
    FROM Table1 t
    

    sqlfiddle

    结果:

    - wadir Umum
        - bagian umum
            - kepala umum
                - SUb bagian Tu
            - bagian umum
        - bagian privasi
    

    将呈现给:

    • 瓦迪尔乌姆
      • bagian umum
        • kepala umum
          • 苏巴江图
        • 巴坚嗯嗯
      • bagian privasi

    更新

    为了匹配问题更新:

    SELECT t.*,
      CHAR_LENGTH(t.dept_code) - CHAR_LENGTH(REPLACE(t.dept_code, '0', '')) AS indent,
      CONCAT(
        REPEAT('-', CHAR_LENGTH(t.dept_code) - CHAR_LENGTH(REPLACE(t.dept_code, '0', ''))),
        t.dept_name
      ) AS indented_name
    FROM Table1 t
    ORDER BY t.dept_code
    

    sqlfiddle

    更新 2

    您的设计的好处是您不需要存储过程来执行此类任务。查看dept_code 作为完整的树路径0 作为分隔符。 1010102 也可以写成1/1/1/2。如果设计正确,您可以通过dept_code 订购。要获得节点深度,您只需计算路径 (dept_code) 中的分隔符 (0)。

    更新 3

    如果你想创建一个递归结构,你最好使用像 PHP 这样的过程语言:

    将来自简单查询 (SELECT * FROM depts) 的 SQL 结果存储到数组中,如下所示:

    // result from query: SELECT * FROM depts
    $depts = array(
        array( // row #0
            'deptid' => 1,
            'dept_code' => '1',
            'dept_name' => 'wadir Umum',
            'parent_deptid' => 0,
        ),
        array( // row #1
            'deptid' => 2,
            'dept_code' => '101',
            'dept_name' => 'bagian umum',
            'parent_deptid' => 1,
        ),
        array( // row #2
            'deptid' => 3,
            'dept_code' => '10101',
            'dept_name' => 'kepala umum',
            'parent_deptid' => 2,
        ),
        array( // row #3
            'deptid' => 4,
            'dept_code' => '102',
            'dept_name' => 'bagian privasi',
            'parent_deptid' => 1,
        ),
        array( // row #4
            'deptid' => 5,
            'dept_code' => '1010101',
            'dept_name' => 'SUb bagian Tu',
            'parent_deptid' => 3,
        ),
        array( // row #5
            'deptid' => 6,
            'dept_code' => '1010102',
            'dept_name' => 'bagian umum',
            'parent_deptid' => 3,
        ),
    );
    

    使用两个foreach 循环构建递归结构:

    $nodes = array();
    $roots = array();
    
    // init nodes
    foreach ($depts as $dept) {
        $dept['childs'] = array(); // init childs
        $nodes[$dept['deptid']] = $dept;
    }
    
    foreach ($depts as $dept) {
        if ($dept['parent_deptid'] == 0) {
            $roots[] = $dept['deptid']; // add root
        } else {
            $nodes[$dept['parent_deptid']]['childs'][] = $dept['deptid']; // add to parents chlids list
        }
    }
    

    数组$roots$nodes 如下所示:

    $roots = array (0 => 1,);
    $nodes = array(
        1 => array(
            'deptid' => 1,
            'dept_code' => '1',
            'dept_name' => 'wadir Umum',
            'parent_deptid' => 0,
            'childs' => array(
                0 => 2,
                1 => 4,
            ) ,
        ) ,
        2 => array(
            'deptid' => 2,
            'dept_code' => '101',
            'dept_name' => 'bagian umum',
            'parent_deptid' => 1,
            'childs' => array(
                0 => 3,
            ) ,
        ) ,
        3 => array(
            'deptid' => 3,
            'dept_code' => '10101',
            'dept_name' => 'kepala umum',
            'parent_deptid' => 2,
            'childs' => array(
                0 => 5,
                1 => 6,
            ) ,
        ) ,
        4 => array(
            'deptid' => 4,
            'dept_code' => '102',
            'dept_name' => 'bagian privasi',
            'parent_deptid' => 1,
            'childs' => array() ,
        ) ,
        5 => array(
            'deptid' => 5,
            'dept_code' => '1010101',
            'dept_name' => 'SUb bagian Tu',
            'parent_deptid' => 3,
            'childs' => array() ,
        ) ,
        6 => array(
            'deptid' => 6,
            'dept_code' => '1010102',
            'dept_name' => 'bagian umum',
            'parent_deptid' => 3,
            'childs' => array() ,
        ) ,
    )
    

    Demo

    现在您可以编写一些递归函数来遍历树:

    function getSubtreeHTMLList($deptsids, $nodes) {
        $result = '<ul>';
        foreach ($deptsids as $deptsid) {
            $result .= '<li>';
            $result .= $nodes[$deptsid]['dept_name'];
            if (count($nodes[$deptsid]['childs'] > 0)) {
                $result .= getSubtreeHTMLList($nodes[$deptsid]['childs'], $nodes);
            }
            $result .= '</li>';
        }
        $result .= '</ul>';
        return $result;
    }
    
    echo getSubtreeHTMLList($roots, $nodes);
    

    创建的 HTML:

    <ul><li>wadir Umum<ul><li>bagian umum<ul><li>kepala umum<ul><li>SUb bagian Tu<ul></ul></li><li>bagian umum<ul></ul></li></ul></li></ul></li><li>bagian privasi<ul></ul></li></ul></li></ul>
    

    Demo

    渲染:

    • 瓦迪尔乌姆姆
      • bagian umum
        • kepala umum
          • 苏巴吉安图
            • 巴坚嗯嗯
          • bagian privasi

          【讨论】:

          • 结果无效 - wadir umum - bagian umum -kepala umum -sub bagian tu
          • 您需要以纯文本形式显示。使用“运行 SQL”按钮附近的下拉菜单。
          • 可以在 sql-fdle 中工作,但是当我想使用 php 查询并在表格中显示它时,我仍然不理解纯文本,我使用 SP 调用树视图
          • 第二个查询为您提供 缩进,您可以在 PHP 中使用它来呈现您的 HTML。
          • 好的,谢谢,但是使用递归的父母和孩子怎么样?
          猜你喜欢
          • 1970-01-01
          • 2011-12-04
          • 1970-01-01
          • 2012-03-02
          • 1970-01-01
          • 2011-08-04
          • 2021-07-28
          • 1970-01-01
          相关资源
          最近更新 更多