我有一张如下表格。
+------+----------------------+-----------+
| Id | category | parent_id |
+------+----------------------+-----------+
| 1 | ELECTRONICS | NULL |
| 2 | TELEVISIONS | 1 |
| 3 | TUBE | 2 |
| 4 | LCD | 2 |
| 5 | PLASMA | 2 |
| 6 | PORTABLE ELECTRONICS | 1 |
| 7 | MP3 PLAYERS | 6 |
| 8 | FLASH | 7 |
| 9 | CD PLAYERS | 6 |
| 10 | 2 WAY RADIOS | 6 |
| 100 | ELECTRONICS | NULL |
| 200 | TELEVISIONS | 100 |
| 300 | TUBE | 200 |
| 400 | LCD | 200 |
| 500 | PLASMA | 200 |
| 600 | PORTABLE ELECTRONICS | 100 |
| 700 | MP3 PLAYERS | 600 |
| 800 | FLASH | 700 |
| 900 | CD PLAYERS | 600 |
| 1000 | 2 WAY RADIOS | 600 |
+------+----------------------+-----------+
有两个树存储为邻接列表。即使有多个树,我想在给定根节点的情况下获取单个树的叶节点。
我正在关注http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/,如果整个表都是树状的话,我们可以得到叶子节点。
SELECT t1.name FROM
category AS t1 LEFT JOIN category as t2
ON t1.category_id = t2.parent
WHERE t2.category_id IS NULL;
答案 0 :(得分:2)
邻接列表模型有局限性, 并且很难为mysql中的特定子树选择所有叶节点 没有其他信息...
如果您有其他信息并知道子树的高度 - 你可以这样做:
SELECT t2.name as name
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
WHERE
t1.name = 'TELEVISIONS' -- subtree
AND t3.name IS NULL -- ensure it is leaf
;
但这是一个非常有限的例子,有许多缺点:
你必须知道子树的高度,子树必须绝对平衡,等等......
我宁愿建议你使用The Nested Set Model
,在这种情况下,查询会看起来
SELECT *
FROM nested_category AS node, nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt AND parent.name = 'TELEVISIONS'
AND node.rgt = node.lft + 1
;
此外它适用于PORTABLE ELECTRONICS
。