当前位置: 首页 > 知识库问答 >
问题:

MySQL:类别树和n层产品

晏和风
2023-03-14

因此,让我们假设我有一个MySQL DB,其中包含以下表:

产品

    < li>id < li >名称 < li >类别id

类别

    < li>id < li >名称 < li>parent_id

查询数据库的最佳方式是什么,以获得从某个类别id开始的所有产品。例如,如果我有一个子类别树,其中基本类别id=1,我如何获得id=1子类别下的所有产品,子类别的数量不确定。

我可以这样做:

SELECT * FROM `Product` WHERE category_id IN (
   SELECT `id` FROM `Category` WHERE parent_id = 1
)

但是,它仅适用于类别id=1的直接子级,而不适用于第二到n级子级。

非常感谢。

编辑

有人建议读一篇关于这方面的博客文章,我也看过那篇关于过去的文章,我做了这个sqlfiddle:

http://sqlfiddle.com/#!2/be72ec/1

正如您在查询中看到的,即使是他们教授的最简单的方法,获取类别树也不会输出任何内容。我错过了什么?其他方法也有同样的问题。

非常感谢。

共有1个答案

伯逸明
2023-03-14

我看了你的剧本,得出了以下结论。

代码的问题在于,您使用的是空值。看看这个sqlfiddle可以看到一个工作示例:http://sqlfiddle.com/#!2/07ef7/1/0

我对你的陈述做了一些更正,现在一切都正常了
以下是我所做更改的列表:

    < li >在create语句中,将“< code > parent _ id bigint(11)unsigned DEFAULT NULL”更改为“< code > parent _ id bigint(11)unsigned NOT NULL DEFAULT 0” < li >删除外键约束,但我无法将“0”用作parent_id < li >插入“0”而不是“NULL”作为parent_id < li >将函数中的数据类型INT更改为BIGINT,因为您在creation语句中使用了此类型 < li >从select语句中删除WHERE子句

我希望这对你有帮助!

下面是一些语句,以防sqlfiddle现在不工作:

CREATE TABLE `Category` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `parent_id` bigint(11) unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  KEY `parent_id` (`parent_id`),
  KEY `ix_hierarchy_parent` (`parent_id`, `id`)
)//


INSERT INTO `Category` (`id`, `name`, `parent_id`)
VALUES
    (1,'Cat Name 1',0),
    (2,'Cat Name 2',0),
    (3,'Cat Name 3',2),
    (4,'Cat Name 4',2),
    (7,'Cat Name 5',4),
    (8,'Cat Name 6',4),
    (9,'Cat Name 7',4),
    (10,'Cat Name 8',4),
    (11,'Cat Name 9',4),
    (12,'Cat Name 10',4),
    (13,'Cat Name 11',2),
    (16,'Cat Name 12',13),
    (17,'Cat Name 13',13),
    (18,'Cat Name 14',13),
    (19,'Cat Name 15',13),
    (20,'Cat Name 16',13),
    (21,'Cat Name 17',13)//


CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value BIGINT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id BIGINT;
        DECLARE _parent_id BIGINT;
        DECLARE _next BIGINT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

        SET _parent_id = @id;
        SET _id = -1;

        IF @id IS NULL THEN
                RETURN NULL;
        END IF;

        LOOP
                SELECT  MIN(id)
                INTO    @id
                FROM    `Category`
                WHERE   parent_id = _parent_id
                        AND id > _id;
                IF @id IS NOT NULL OR _parent_id = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  id, parent_id
                INTO    _id, _parent_id
                FROM    `Category`
                WHERE   id = _parent_id;
        END LOOP;       
END//

SELECT  CONCAT(REPEAT('    ', level - 1), CAST(hi.id AS CHAR)) AS treeitem, hi.name, parent_id, 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, `Category`
        WHERE   @id IS NOT NULL
        ) ho
JOIN    `Category` hi
ON      hi.id = ho.id
 类似资料:
  • 我的起点是一个包含类别ID及其父ID的数组,来自Virtuemart categories表,如下所示: 我需要有一个字符串,每个最后类别的孩子完整的路径由/(斜杠)之间的孩子和由,(逗号)之间的第一级父母 我的输出应该是: 我可以把启动数组转换成这个

  • 问题内容: 我试图从我的MySQL数据库中按层次结构获取所有类别和子类别: 我的结果应该是这样(只是示例): 猫A 子猫1 Sub_Sub_Cat 1 Sub_Sub_Cat 2 子猫2 猫B C猫 … MySQL代码: 简而言之,如何在使用 PHP代码 的层次结构中获得它? 问题答案: 使用邻接表模型时,您可以一次性生成结构。 取自一遍父子数组结构(2007年9月; Nate Weiner撰写)

  • 我的数据库中有两个表: 我怎么能这样回报: 我在类别表中使用“WITH RECURSIVE”,但找不到将产品表与1次查询相结合的方法。我使用这里的例子 最好的方法是什么?

  • 问题内容: 我是mysql的新手。这是我的桌子: 类别表: 每个类别都有一个父项,我想准备它们以显示在下拉菜单中。 这就是我想要得到的: 在这里,类别没有顺序,我的代码必须为远离父母的孩子类别提供顺序。根据每个类别的父母的深度提供姓名前的缩进。每个类别的孩子数没有限制,但是类别总数不超过100。 有没有查询可以给出这样的结果?我更喜欢可以在PHP框架中以活动记录形式运行的查询。 问题答案: 这个

  • 问题内容: 我有一个包含一个类别的FK的产品表,创建类别表的方式是每个类别都可以有一个父类别,例如: 我需要进行选择查询,如果选择的类别是“处理器”,它将返回英特尔,奔腾,Core 2 Duo,AMD等产品。 我考虑过要创建某种“缓存”,该缓存将为数据库中的每个类别存储层次结构中的所有类别,并在where子句中包含“ IN”。这是最好的解决方案吗? 问题答案: 最好的解决方案是在数据库设计阶段。您

  • 我有两个表格;类别和产品。对于每个类别,我想计算其所有子类别中有多少产品。我已经计算了每个类别中有多少。示例表是: 类别: 产品: 所以我想让我的函数: 它只需要作为选择查询,无需更新数据库。 有什么想法吗? 编辑:SQL小提琴:http://sqlfiddle.com/#!2/1941a/4/0