Oft möchte man eine Baumstruktur in einer MySQL-Tabelle selektieren.
+--------+-------------------+
| Parent | Child |
+--------+-------------------+
| 1 | 2,3 |
| 2 | 4,5,6,7,8,9,10,11 |
| 6 | 12,13,14 |
| 8 | 15,16,17,18 |
| 12 | 19 |
| 14 | 20,21,22 |
| 19 | 23 |
+--------+-------------------+
DROP PROCEDURE IF EXISTS objsubtree;
DELIMITER go
CREATE PROCEDURE objsubtree( root char(18) )
BEGIN
DROP TABLE IF EXISTS objsubtree;
CREATE TABLE objsubtree ( ObjectUID char(18), ContainerUID char(18), level int, Primary Key(ObjectUID,ContainerUID) ) ENGINE=MEMORY;
SELECT ObjectUID, ContainerUID, 0 AS level
FROM oms_link
WHERE ContainerUID = root;
REPEAT
INSERT IGNORE INTO objsubtree
SELECT f.ObjectUID, f.ContainerUID, s.level+1
FROM oms_link AS f
JOIN objsubtree AS s ON f.ContainerUID = s.ObjectUID;
UNTIL Row_Count() = 0 END REPEAT;
SELECT * FROM objsubtree;
DROP TABLE IF EXISTS objsubtree;
END ;
go
DELIMITER ;
call objsubtree('101:12');
Probier bitten nochfolgende Implementation aus:
Hierarchische Querys in MySQL
Show archive.org snapshot
In MySQL 8.0 gibt es diesen neuen Rekursiven SELECT-Befehl:
Mysql Adjacency List Tree
Show archive.org snapshot
Und das ist die Lösung
Alle Childs und Deep-Childs mit LevelNumber zurückgeben (ausgehend von 101:12)
WITH RECURSIVE link_path (ObjectUID, ContainerUID, LevelNumber) AS
(
SELECT ObjectUID, ContainerUID, 0 LevelNumber
FROM oms_link
WHERE ContainerUID = '101:12'
UNION ALL
SELECT c.ObjectUID, c.ContainerUID, cp.LevelNumber + 1
FROM link_path AS cp JOIN oms_link AS c
ON cp.ObjectUID = c.ContainerUID
)
SELECT * FROM link_path
ORDER BY LevelNumber;
Und hier ein Beispiel, wie alle Parent-Elemente ausgehend von 101:12 zurückgegeben werden:
WITH RECURSIVE link_path (ObjectUID, ContainerUID, LevelNumber) AS
(
SELECT ObjectUID, ContainerUID, 0 AS LevelNumber
FROM oms_link
WHERE ObjectUID = '301:1' -- child node
UNION ALL
SELECT c.ObjectUID, c.ContainerUID, cp.LevelNumber + 1
FROM link_path AS cp JOIN oms_link AS c
ON cp.ContainerUID = c.ObjectUID
)
SELECT * FROM link_path
GROUP BY ObjectUID, ContainerUID
ORDER BY LevelNumber
Posted by Stephan Blaurock to Programming KB (2018-04-18 08:34)