MySQL的:获取所有子类,子孙

问题描述:

我已经MySQL表定义为:MySQL的:获取所有子类,子孙

类:CATEGORY_ID,CATEGORY_NAME,parent_category_id

我正在寻找一个很好的SQL查询将检索给定的所有后代CATEGORY_ID。这意味着,它的孩子和孩子的孩子。

如果有帮助,我们可以假设*别(3)。这个查询可以在任何级别发送(根,级别2,级别3)。

谢谢!

Nathan

有几种方法可以将树存储在数据库中。有一个关于sitepoint一个梦幻般的文章描述的所有技术:

http://articles.sitepoint.com/article/hierarchical-data-database/2

的一个,如果你希望能够得到一棵树的整个部分在一个查询修改预购树的遍历这是最合适的。

这种技术也被称为嵌套集。这里还有更多的信息,如果你想了解某个主题的文献:

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

+0

如何使用现有的结构? – 2009-11-06 22:23:58

+0

使用您当前的表结构,您必须使用递归查询。 – jonnii 2009-11-06 22:25:56

MySQL不支持递归查询,但可以使用while循环存储过程中发现的所有后代。请参阅此book sampleThe edge list部分。

如果你想用这个结构,最大3级就可以加入表本身三次:

SELECT 
    c1.id AS level_1, 
    c2.id AS level_2, 
    c3.id AS level_3 
FROM categories c1 
LEFT JOIN categories c2 ON c1.id = c2.parent_id 
LEFT JOIN categories c3 ON c2.id = c3.parent_id 
WHERE c1.parent_id IS NULL 

我假定,父类有PARENT_ID NULL。

一些示例:

DECLARE @categories TABLE 
(
    id INT, 
    parent_id INT 
) 

INSERT INTO @categories(id,parent_id) VALUES(1,NULL) 
INSERT INTO @categories(id,parent_id) VALUES(4,1) 
INSERT INTO @categories(id,parent_id) VALUES(5,1) 
INSERT INTO @categories(id,parent_id) VALUES(6,5) 
INSERT INTO @categories(id,parent_id) VALUES(2,NULL) 

SELECT * FROM @categories 

SELECT c1.id AS level_1, c2.id AS level_2, 
    c3.id AS level_3 
FROM @categories c1 
LEFT JOIN @categories c2 ON c1.id = c2.parent_id 
LEFT JOIN @categories c3 ON c2.id = c3.parent_id 
WHERE c1.parent_id IS NULL 

返回:

level_1 | level_2 | level_3 
--------------------------- 
1  | 4  | NULL 
1  | 5  | 6 
2  | NULL | NULL 
+0

我喜欢你在这里得到的地方,除了结尾格式不是很容易使用(这个整个查询然后被用作子查询,例如WHERE categoryId IN(调用后裔列表) 我们是否可以创建一个查询来生成一个缓存表,该列将包含parent_category_id,descendant。它会列出每个给定类别的所有后代? – 2009-11-06 22:59:06

+0

这不是一个解决方案,只是一个补丁,通常情况下我们无法预测类别级别。而且,至少,硬编码是非常糟糕的。 – Lambrusco 2016-11-30 08:40:59

+1

@Lambrusco在答案7年后。谨慎给予适当的解决方案? – 2016-11-30 09:56:22

它可以在一个单一的查询和一块递归后端代码逻辑来完成:Formatting a multi-level menu using only one query

如果你也做PHP,这篇文章附带PHP作为奖金的例子,但翻译到另一种语言并不困难。由于您没有提及您使用的服务器端语言,因此我无法给出任何提示。

希望这会有所帮助。