代码之家  ›  专栏  ›  技术社区  ›  meleyal

在mysql/php中,使用id/parent_id模型获取记录的所有父级的最简单方法是什么?

  •  2
  • meleyal  · 技术社区  · 16 年前

    我在寻找最简单的方法,使用邻接列表/单表继承模型递归地从数据库获取所有父元素( id, parent_id ).

    $sql = "SELECT
                 e.id,
                 TIME_FORMAT(e.start_time, '%H:%i') AS start_time,
                 $title AS title,
                 $description AS description,
                 $type AS type,
                 $place_name AS place_name,
                 p.parent_id AS place_parent_id,
                 p.city AS place_city,
                 p.country AS place_country
             FROM event AS e
             LEFT JOIN place AS p ON p.id = e.place_id                          
             LEFT JOIN event_type AS et ON et.id = e.event_type_id
             WHERE e.day_id = '$day_id'
             AND e.private_flag = 0
             ORDER BY start_time";
    

    每个 event 链接到 place 地方 地方 (约5层深)

    用mysql一次选择就可以做到吗?

    $events 数组,添加 place_parent_X 元素,但不确定如何实现这一点。

    3 回复  |  直到 16 年前
        1
  •  7
  •   Quassnoi    16 年前

    MySQL ,但您需要创建一个函数并在查询中使用。

    有关详细解释,请参阅我的博客中的以下条目:

    CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
    NOT DETERMINISTIC
    READS SQL DATA
    BEGIN
            DECLARE _id INT;
            DECLARE _parent INT;
            DECLARE _next INT;
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;
    
            SET _parent = @id;
            SET _id = -1;
    
            IF @id IS NULL THEN
                    RETURN NULL;
            END IF;
    
            LOOP
                    SELECT  MIN(id)
                    INTO    @id
                    FROM    place
                    WHERE   parent = _parent
                            AND id > _id;
                    IF @id IS NOT NULL OR _parent = @start_with THEN
                            SET @level = @level + 1;
                            RETURN @id;
                    END IF;
                    SET @level := @level - 1;
                    SELECT  id, parent
                    INTO    _id, _parent
                    FROM    place
                    WHERE   id = _parent;
            END LOOP;
    END
    
    SELECT  id, parent
    FROM    (
            SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
            FROM    (
                    SELECT  @start_with := 0,
                            @id := @start_with,
                            @level := 0
                    ) vars, t_hierarchy
            WHERE   @id IS NOT NULL
            ) ho
    JOIN    place hi
    ON      hi.id = ho.id
    

    @start_with 变量)

    要查找给定节点的所有祖先,可以使用不带函数的简单查询:

    SELECT  @r AS _id,
            @r := (
            SELECT  parent
            FROM    place
            WHERE   id = _id
            ) AS parent
    FROM    (
            SELECT  @r := @node_id
            ) vars,
            place
    

    要使这两个解决方案在合理的时间内工作,您需要在这两个解决方案上都有索引 id parent

    确保您的 身份证件 定义为 PRIMARY KEY 你有第二天的索引 起源 .

        2
  •  0
  •   Matthew Groves    16 年前

    标准的父子数据库设计是不可能的。

    但是,您可以使用 nested set

        3
  •  0
  •   l0b0    16 年前

    看起来最简单的是 nested sets

    推荐文章