0

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

此外,我想用一个写得很好的 SQL 查询来解决这个问题,而不是我的 PHP 代码中的递归函数,因为这个特性会被使用很多。

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

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

表“文章”:

  • article_id
  • 类别ID
  • ...

表类别

  • 类别ID
  • parent_id
  • ...

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

意思是,其中“10”是父母和所有的孩子,向上是10是孩子和所有的父母。

没有递归php函数可能吗?

谢谢你。

4

4 回答 4

3

鉴于您使用的是 MySQL,不可能使用您正在使用的邻接列表设计在一个查询中获取整个树。

其他一些品牌的数据库支持 SQL 扩展来处理这种设计。Oracle、Microsoft SQL Server、IBM DB2 和 PostgreSQL 8.4(目前处于测试阶段)支持 SQL 扩展。

存在其他允许您更有效地查询树的数据库设计。这个问题已在 StackOverflow、博客和文章中多次解决。

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

于 2009-06-03T07:47:56.517 回答
2

这在 中是可能的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

有关更多详细信息,请参阅我的博客中的此条目:

于 2009-06-03T15:41:22.363 回答
1

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

于 2009-06-03T07:40:02.757 回答
0

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

http://gist.github.com/104357

于 2009-06-03T09:07:47.200 回答