mysql - 选择MySQL表中的树路径

标签 mysql recursion tree hierarchical

我有一个像这样的 MySQL 表:

| CategoryId |          Name | CategoryParentId |
|------------|---------------|------------------|
|          0 |  Tech Support |           (null) |
|          1 | Configuration |                0 |
|          2 |     Questions |                1 |
|          3 |         Sales |           (null) |
|          4 |     Questions |                3 |
|          5 |         Other |           (null) |

这是我在查询 ID 2 时想要的输出(例如):

技术支持/配置/问题

如何在无需进行多次连接的情况下执行此操作?

Fiddle

编辑:不确定是否是最好的方法,但我通过创建一个函数解决了:

DELIMITER $$

CREATE FUNCTION get_full_tree (CategoryId int) RETURNS VARCHAR(200)

BEGIN
SET @CategoryParentId = (SELECT CategoryParentId FROM category c WHERE c.CategoryId = CategoryId);
SET @Tree = (SELECT Name FROM category c WHERE c.CategoryId = CategoryId);
WHILE (@CategoryParentId IS NOT NULL) DO
    SET @ParentName = (SELECT Name FROM category c WHERE c.CategoryId = @CategoryParentId);
    SET @Tree = CONCAT(@ParentName, '/', @Tree);
    SET @CategoryParentId = (SELECT CategoryParentId FROM category c WHERE c.CategoryId = @CategoryParentId);
END WHILE;
RETURN @Tree;
END $$
DELIMITER ;

我现在可以执行此查询:

SELECT CategoryId, get_full_tree(CategoryId) FROM category

最佳答案

您可以创建一个新表,将其命名为“hierarchy”(可能是一个更好的名称),我们将在其中存储类别的所有祖先。

CREATE TABLE `hierarchy` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `parent` int(11) NOT NULL,
  `child` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

例如,在本例中,对于问题,即ID->2,我们将有以下条目:

id  parent     child
====================            
6     0         2
7     1         2
8     2         2

对于整个示例,表格的内容为:

id       parent     child
===========================
1           0           0
2           3           3
3           5           5
4           0           1
5           1           1
6           0           2
7           1           2
8           2           2
9           3           4
10          4           4

现在,每当您想要检索节点的整个祖先时,请执行以下查询:

select name from category where id in (select parent from hierarchy where child = 2 order by id ASC)

上述查询将返回问题(ID->2)的所有祖先名称,即

name
==================
Tech Support
Configuration
Questions

为了完整起见,下面是category表的内容

id             Name
============================
0             Tech Support
1             Configuration
2             Questions
3             Sales
4             Questions
5             Other

注意这只是一个想法,我相信您绝对可以在此基础上构建更优雅的解决方案。

关于mysql - 选择MySQL表中的树路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44232637/

相关文章:

算法设计。最佳,最有效的解决方案

sql - 在 Postgres 中订购 WITH RECURSIVE 查询

tree - 如何在 VIRTUAL 模式下以编程方式在 SWT 树上触发 setData 事件

sql - Ruby 中的树数据结构持久化

php - 如何使用php进行多个关键字搜索

php - 已建立 MySQL 连接但查询失败

mysql - 选择特定列数据的多次出现

php - 如何使用 php 代码将数据库表中的值获取到数组?

java - Java中的递归字符串和删除字符

javascript - 原生 JavaScript 类型是如何用 Elm 编写的?