繁体   English   中英

MySQL父级->子查询

[英]MySQL parent -> child query

我正在使用mySQL,并且处于一种情况下,我需要从一个表中选择与父表中任何级别的ID匹配的表中的数据->另一表中的子数据层次结构。

另外,我想通过编写良好的SQL查询而不是PHP代码中的递归函数来解决此问题,因为此功能将被大量使用。

我确实尝试搜索,但偶然发现了许多类似的问题(大多数问题都已解决),但是没有一个问题对我有帮助。

为了说明情况,这是我当前的设置

表“文章”:

  • article_id
  • category_id
  • ...

表类别

  • category_id
  • parent_id
  • ...

我需要从“ articles.category_id”为10的“ articles”中选择所有文章。还要从“ categories.category_id” 10所属的树中接收所有类别的所有文章。

意思是,其中“ 10”是父母及其所有子女,向上则是“ 10”是孩子及其所有父母。

没有递归的php函数可能吗?

谢谢。

假设您使用的是MySQL,则无法使用正在使用的邻接列表设计在一个查询中获取整棵树。

其他一些数据库品牌支持SQL扩展来处理这种设计。 Oracle,Microsoft SQL Server,IBM DB2和PostgreSQL 8.4(当前处于beta版)支持SQL扩展。

存在其他数据库设计,可让您更有效地查询树。 在StackOverflow,博客和文章中已经多次解决了这个问题。

您还可以阅读Joe Celko 撰写的用于Smarties的SQL中的树和层次结构 ”,其中深入介绍了几种此类设计。

这可以在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    categories
                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    categories
                WHERE   id = _parent;
        END LOOP;
END

并在查询中使用它:

SELECT  id, parent, level
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, categories 
        WHERE   @id IS NOT NULL
        ) ho
JOIN    categories hi
ON      hi.id = ho.id

有关更多详细信息,请参见我的博客中的此项:

在关系数据库中存储分层数据的最常见模式是相邻列表或已修改的预排序(也称为嵌套集) 另一种选择是使用物化路径,它基本上是一种缓存机制,位于相邻列表的顶部。 另请参阅此表以了解优缺点

我不知道这对您有多大帮助,但是我编写了一个小函数,该函数使用单个MySQL查询生成分层树。 基本上,所有重要的逻辑都移到了PHP中。 我的解决方案使用邻接列表模型,然后利用PHP引用,以通过一个平面树来构建树数据结构。 看看下面的要点,看看是否有启发。 我会为您提供更多帮助,但是在工作中我必须解决一些问题。

http://gist.github.com/104357

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM