美文网首页
mysql 树查询

mysql 树查询

作者: marioplus12 | 来源:发表于2020-08-11 13:32 被阅读0次

    主要是为每列数据加上一个id链方便查询

    • 初始数据
    CREATE TABLE node
    (
        id   BIGINT(20) AUTO_INCREMENT NOT NULL,
        pId  BIGINT(20)                NOT NULL,
        name VARCHAR(20)               NULL,
        PRIMARY KEY (id)
    );
    
    TRUNCATE node;
    INSERT INTO node
    VALUES (),(),(),();
    INSERT INTO node(id, pId)
    VALUES (@id := 5, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1),
           (@id := @id + 1, FLOOR(rand() * (@id - 1)) + 1)
    ;
    
    UPDATE node
    SET name= concat('node ', id)
    WHERE TRUE;
    
    mysql> SELECT * from node;
    +----+------+---------+
    | id | pId  | name    |
    +----+------+---------+
    |  1 | NULL | node 1  |
    |  2 | NULL | node 2  |
    |  3 | NULL | node 3  |
    |  4 | NULL | node 4  |
    |  5 |    1 | node 5  |
    |  6 |    5 | node 6  |
    |  7 |    3 | node 7  |
    |  8 |    2 | node 8  |
    |  9 |    1 | node 9  |
    | 10 |    4 | node 10 |
    | 11 |    1 | node 11 |
    | 12 |   11 | node 12 |
    | 13 |    8 | node 13 |
    | 14 |    3 | node 14 |
    | 15 |    4 | node 15 |
    | 16 |    8 | node 16 |
    | 17 |   13 | node 17 |
    | 18 |    9 | node 18 |
    | 19 |    1 | node 19 |
    | 20 |   15 | node 20 |
    | 21 |   12 | node 21 |
    | 22 |   16 | node 22 |
    | 23 |   20 | node 23 |
    | 24 |    4 | node 24 |
    | 25 |    7 | node 25 |
    | 26 |   19 | node 26 |
    | 27 |   25 | node 27 |
    | 28 |   12 | node 28 |
    | 29 |   12 | node 29 |
    | 30 |   23 | node 30 |
    | 31 |   18 | node 31 |
    | 32 |   22 | node 32 |
    | 33 |   20 | node 33 |
    +----+------+---------+
    33 rows in set (0.00 sec)
    
    • 8.0以下使用函数查询
    DELIMITER //
    CREATE FUNCTION getIdPath(givenID BIGINT) RETURNS VARCHAR(1024)
        DETERMINISTIC
    BEGIN
        DECLARE idPath VARCHAR(1024);
        DECLARE dm CHAR(1);
        DECLARE tmpId BIGINT;
    
        SET idPath = '';
        SET dm = '';
        SET tmpId = givenID;
        -- 非根节点需要满足的条件
        WHILE tmpId IS NOT NULL
            DO
                SELECT pId INTO tmpId FROM node WHERE id = tmpId;
                -- 非根节点需要满足的条件
                IF tmpId IS NOT NULL THEN
                    SET idPath = CONCAT(idPath, dm, tmpId);
                    SET dm = ',';
                END IF;
            END WHILE;
        RETURN idPath;
    END //
    DELIMITER ;
    
    mysql> SELECT *, getIdPath(id) idPath FROM node;
    +----+------+---------+------------+
    | id | pId  | name    | idPath     |
    +----+------+---------+------------+
    |  1 | NULL | node 1  |            |
    |  2 | NULL | node 2  |            |
    |  3 | NULL | node 3  |            |
    |  4 | NULL | node 4  |            |
    |  5 |    1 | node 5  | 1          |
    |  6 |    5 | node 6  | 5,1        |
    |  7 |    3 | node 7  | 3          |
    |  8 |    2 | node 8  | 2          |
    |  9 |    1 | node 9  | 1          |
    | 10 |    4 | node 10 | 4          |
    | 11 |    1 | node 11 | 1          |
    | 12 |   11 | node 12 | 11,1       |
    | 13 |    8 | node 13 | 8,2        |
    | 14 |    3 | node 14 | 3          |
    | 15 |    4 | node 15 | 4          |
    | 16 |    8 | node 16 | 8,2        |
    | 17 |   13 | node 17 | 13,8,2     |
    | 18 |    9 | node 18 | 9,1        |
    | 19 |    1 | node 19 | 1          |
    | 20 |   15 | node 20 | 15,4       |
    | 21 |   12 | node 21 | 12,11,1    |
    | 22 |   16 | node 22 | 16,8,2     |
    | 23 |   20 | node 23 | 20,15,4    |
    | 24 |    4 | node 24 | 4          |
    | 25 |    7 | node 25 | 7,3        |
    | 26 |   19 | node 26 | 19,1       |
    | 27 |   25 | node 27 | 25,7,3     |
    | 28 |   12 | node 28 | 12,11,1    |
    | 29 |   12 | node 29 | 12,11,1    |
    | 30 |   23 | node 30 | 23,20,15,4 |
    | 31 |   18 | node 31 | 18,9,1     |
    | 32 |   22 | node 32 | 22,16,8,2  |
    | 33 |   20 | node 33 | 20,15,4    |
    +----+------+---------+------------+
    33 rows in set (0.00 sec)
    
    • 8.0 使用递归CTE
    WITH RECURSIVE nodeTree AS
                       (
                           SELECT id, cast(id AS CHAR) idPath
                           FROM node
                            -- 根节点满足条件
                           WHERE pId IS NULL
                           UNION ALL
                           SELECT n.id, concat(idPath, ',', cast(n.id AS CHAR))
                           FROM nodeTree AS nt
                                JOIN node AS n ON nt.id = n.pId
                       )
    SELECT *
    FROM nodeTree
    
    +------+------+---------+---------------+
    | id   | pId  | name    | idPath        |
    +------+------+---------+---------------+
    |    1 | NULL | node 1  | 1             |
    |    2 | NULL | node 2  | 2             |
    |    3 | NULL | node 3  | 3             |
    |    4 | NULL | node 4  | 4             |
    |    5 |    1 | node 5  | 1,5           |
    |    7 |    3 | node 7  | 3,7           |
    |    8 |    2 | node 8  | 2,8           |
    |    9 |    1 | node 9  | 1,9           |
    |   10 |    4 | node 10 | 4,10          |
    |   11 |    1 | node 11 | 1,11          |
    |   14 |    3 | node 14 | 3,14          |
    |   15 |    4 | node 15 | 4,15          |
    |   19 |    1 | node 19 | 1,19          |
    |   24 |    4 | node 24 | 4,24          |
    |    6 |    5 | node 6  | 1,5,6         |
    |   12 |   11 | node 12 | 1,11,12       |
    |   13 |    8 | node 13 | 2,8,13        |
    |   16 |    8 | node 16 | 2,8,16        |
    |   18 |    9 | node 18 | 1,9,18        |
    |   20 |   15 | node 20 | 4,15,20       |
    |   25 |    7 | node 25 | 3,7,25        |
    |   26 |   19 | node 26 | 1,19,26       |
    |   17 |   13 | node 17 | 2,8,13,17     |
    |   21 |   12 | node 21 | 1,11,12,21    |
    |   22 |   16 | node 22 | 2,8,16,22     |
    |   23 |   20 | node 23 | 4,15,20,23    |
    |   27 |   25 | node 27 | 3,7,25,27     |
    |   28 |   12 | node 28 | 1,11,12,28    |
    |   29 |   12 | node 29 | 1,11,12,29    |
    |   31 |   18 | node 31 | 1,9,18,31     |
    |   33 |   20 | node 33 | 4,15,20,33    |
    |   30 |   23 | node 30 | 4,15,20,23,30 |
    |   32 |   22 | node 32 | 2,8,16,22,32  |
    +------+------+---------+---------------+
    33 rows in set (0.00 sec)
    

    相关文章

      网友评论

          本文标题:mysql 树查询

          本文链接:https://www.haomeiwen.com/subject/sdkdrktx.html