MySQL:按层次结构排序,无需编程递归

时间:2017-12-05 11:37:23

标签: php mysql recursion

我有一张包含以下结构和样本值的表格 -

ls_navigator

+----+------------------+-----------+
| id | title            | parent_id |
+----+------------------+-----------+
|  1 | English Language |      NULL |
|  2 | ICT              |      NULL |
|  3 | Class IX         |      NULL |
|  4 | Class X          |      NULL |
|  5 | Class XI         |      NULL |
|  6 | Class XII        |      NULL |
|  7 | Reading          |         1 |
|  8 | Writing          |         1 |
|  9 | Speaking         |         1 |
| 10 | Listening        |         1 |
| 11 | abc              |         7 |
| 12 | xyz              |         7 |
| 13 | asdfg            |        12 |
| 14 | qwert            |         8 |
+----+------------------+-----------+

此处parent_id表示同一个表的父元素。现在我想要选择这样的数据,以便子行在父行之后作为以下结果。

+----+------------------+-----------+
| id | title            | parent_id |
+----+------------------+-----------+
|  1 | English Language |      NULL |
|  7 | Reading          |         1 |
| 11 | abc              |         7 |
| 12 | xyz              |         7 |
| 13 | asdfg            |        12 |
|  8 | Writing          |         1 |
| 14 | qwert            |         8 |
|  9 | Speaking         |         1 |
| 10 | Listening        |         1 |
|  2 | ICT              |      NULL |
|  3 | Class IX         |      NULL |
|  4 | Class X          |      NULL |
|  5 | Class XI         |      NULL |
|  6 | Class XII        |      NULL |
+----+------------------+-----------+

我知道可以使用递归从编程端完成,但我试图生成一个查询来获得这样的结果。

我试过这样,但它会返回错误的顺序和重复的数据。

SELECT DISTINCT *
FROM (SELECT
        *,
        LPAD(parent_id, 3, '0') AS id1
      FROM ls_navigator

      UNION

      SELECT
        *,
        LPAD(id, 3, '0') AS id1
      FROM ls_navigator
     ) AS t
WHERE id1 IS NOT NULL
ORDER BY id1;

PHP 代码段在我的案例中按预期执行 -

private function get_content_children($parent_id = null, $hyphen = '')
{
    if ($parent_id === null) $where = "parent_id is null";
    else $where = "parent_id = $parent_id";

    $resData = [];

    $q = $this->db->get_where("ls_contents", $where);
    if ($q->num_rows() > 0) {
        $data = $q->result();
        foreach ($data as $row) {
            $row->hypen = $hyphen;
            $resData[] = $row;
            $resData = array_merge($resData, $this->get_content_children($row->id, $hyphen . ' -'));
        }
    }
    return $resData;
} 

0 个答案:

没有答案