如何使用存储过程在mysql中创建树视图

时间:2016-05-16 09:24:26

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

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

3 个答案:

答案 0 :(得分:0)

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

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

请在查询中更改您的tableName。

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

编辑:实际上如果parent_deptid是实际的父ID,那么你只需要按parent_deptid排序,然后是dept_code。但是,parent_deptid看起来不像相应的父ID,而是像#34; depth"代替。

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的最大长度。

答案 1 :(得分:0)

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

SELECT * 
FROM tableName
ORDER BY dept_code

答案 2 :(得分: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

将呈现给:

  • wadir Umum
    • bagian umum
      • kepala umum
        • SUb bagian Tu
      • bagian 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订购即可。要获得节点深度,您只需要计算路径(0)中的分隔符(dept_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() ,
    ) ,
)

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

渲染:

  • wadir Umum
    • bagian umum
      • kepala umum
        • SUb bagian Tu
        • bagian umum < ul>
  • bagian privasi