-1

我很困惑。我不知道如何使用存储过程在 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
4

3 回答 3

0

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

SELECT * 
FROM tableName
ORDER BY dept_code
于 2016-05-16T10:16:14.527 回答
0

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

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 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视为带有分隔符的完整树路径。也可以写成。如果设计正确,您可以订购。要获得节点深度,您只需计算路径 () 中的分隔符 ( )。010101021/1/1/2dept_code0dept_code

更新 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() ,
    ) ,
)

演示

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

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>

演示

渲染:

  • 瓦迪尔乌姆
    • 巴江乌姆
      • 凯帕拉乌姆
        • 苏巴吉安图
          • 巴江乌姆
        • Bagian privasi
        于 2016-05-16T12:52:20.150 回答
        0

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

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

        请在查询中更改您的 tableName。

        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 的最大长度。
        于 2016-05-16T09:42:05.300 回答