如何在mysql中获取树状结构的数据?
How can fetch data like a tree structure in mysql?
如果我搜索 Pro
,我需要获取像 Electronics > Mobile > Iphone > Pro
这样的数据。
也就是说,
Pro
parent_id
是 3
sibling_order
3
是 Iphone
.
Iphone
parent_id
是 2
sibling_order
2
是 Mobile
.
Mobile
parent_id
是 1
sibling_order
1
是 Electronics
.
另一个例子:
如果我搜索 Mobile
,那么我需要获取像 Electronics/Mobile
这样的数据。
我尝试了递归查询,但它不起作用 Syntax error
。
WITH RECURSIVE category_path (id, name, path) AS
(
SELECT id, name, name as path
FROM categories
WHERE parent_id IS NULL
UNION ALL
SELECT c.id, c.name, CONCAT(cp.path, ' > ', c.name)
FROM category_path AS cp JOIN categories AS c
ON cp.id = c.parent_id
)
SELECT * FROM category_path
ORDER BY path;
如有任何帮助,我们将不胜感激。
id name sibling_order parent_id
1 Electronics 1 NULL
2 Mobile 2 1
3 Iphone 3 2
4 Pro 4 3
5 SE 5 3
6 XR 6 3
7 Samsung 7 2
8 Galaxy 8 8
9 Note 9 8
10 Home & Furniture 10 NULL
11 Kitchen Storage 11 11
12 Lunch Box 12 12
13 Living Room Furniture 13 11
14 Sofa 14 13
我通过创建一个调用递归过程的函数解决了这个问题
DROP PROCEDURE IF EXISTS `spCategoryPath`;
DELIMITER //
CREATE PROCEDURE `spCategoryPath`(IN `categoryID` INT UNSIGNED, OUT `return_path` TEXT)
BEGIN
DECLARE categoryName VARCHAR(50);
DECLARE categoryParentId INT;
DECLARE pathResult TEXT;
SET max_sp_recursion_depth=50;
SELECT name, parent_id INTO categoryName, categoryParentId FROM categories WHERE id=categoryID;
IF ISNULL(categoryParentId) THEN
SELECT categoryName INTO return_path;
ELSE
CALL spCategoryPath(categoryParentId, pathResult);
SELECT CONCAT(pathResult, ' > ', categoryName) INTO return_path;
END IF;
END //
DELIMITER ;
DROP FUNCTION IF EXISTS `fnCategoryPath`;
DELIMITER //
CREATE FUNCTION fnCategoryPath(`categoryID` INT) RETURNS TEXT DETERMINISTIC
BEGIN
DECLARE pathResult TEXT;
CALL spCategoryPath(categoryID, pathResult);
RETURN pathResult;
END //
DELIMITER ;
函数是这样执行的:
SELECT fnCategoryPath(6);
生成以下结果:
电子产品 > 手机 > Iphone > XR
如果我搜索 Pro
,我需要获取像 Electronics > Mobile > Iphone > Pro
这样的数据。
也就是说,
Pro
parent_id
是 3
sibling_order
3
是 Iphone
.
Iphone
parent_id
是 2
sibling_order
2
是 Mobile
.
Mobile
parent_id
是 1
sibling_order
1
是 Electronics
.
另一个例子:
如果我搜索 Mobile
,那么我需要获取像 Electronics/Mobile
这样的数据。
我尝试了递归查询,但它不起作用 Syntax error
。
WITH RECURSIVE category_path (id, name, path) AS
(
SELECT id, name, name as path
FROM categories
WHERE parent_id IS NULL
UNION ALL
SELECT c.id, c.name, CONCAT(cp.path, ' > ', c.name)
FROM category_path AS cp JOIN categories AS c
ON cp.id = c.parent_id
)
SELECT * FROM category_path
ORDER BY path;
如有任何帮助,我们将不胜感激。
id name sibling_order parent_id
1 Electronics 1 NULL
2 Mobile 2 1
3 Iphone 3 2
4 Pro 4 3
5 SE 5 3
6 XR 6 3
7 Samsung 7 2
8 Galaxy 8 8
9 Note 9 8
10 Home & Furniture 10 NULL
11 Kitchen Storage 11 11
12 Lunch Box 12 12
13 Living Room Furniture 13 11
14 Sofa 14 13
我通过创建一个调用递归过程的函数解决了这个问题
DROP PROCEDURE IF EXISTS `spCategoryPath`;
DELIMITER //
CREATE PROCEDURE `spCategoryPath`(IN `categoryID` INT UNSIGNED, OUT `return_path` TEXT)
BEGIN
DECLARE categoryName VARCHAR(50);
DECLARE categoryParentId INT;
DECLARE pathResult TEXT;
SET max_sp_recursion_depth=50;
SELECT name, parent_id INTO categoryName, categoryParentId FROM categories WHERE id=categoryID;
IF ISNULL(categoryParentId) THEN
SELECT categoryName INTO return_path;
ELSE
CALL spCategoryPath(categoryParentId, pathResult);
SELECT CONCAT(pathResult, ' > ', categoryName) INTO return_path;
END IF;
END //
DELIMITER ;
DROP FUNCTION IF EXISTS `fnCategoryPath`;
DELIMITER //
CREATE FUNCTION fnCategoryPath(`categoryID` INT) RETURNS TEXT DETERMINISTIC
BEGIN
DECLARE pathResult TEXT;
CALL spCategoryPath(categoryID, pathResult);
RETURN pathResult;
END //
DELIMITER ;
函数是这样执行的:
SELECT fnCategoryPath(6);
生成以下结果:
电子产品 > 手机 > Iphone > XR