示例数据库(嵌套集模型中的类别):
CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`lft` int(11) NOT NULL,
`rgt` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
INSERT INTO category(name, lft, rgt) values("Primary", 0, 1000);
INSERT INTO category(name, lft, rgt) values("Secondary", 1, 500);
INSERT INTO category(name, lft, rgt) values("Tertiary", 2, 20);
INSERT INTO category(name, lft, rgt) values("Tertiary2", 21, 30);
我想获得底层子类别的所有父母(可能是concat?),如下所示:
Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2
除了使用BETWEEN lft和rgt以及CONCAT之外,我还非常困难,可以使用一些有关获得所需结果的提示和信息。谢谢!
答案 0 :(得分:0)
请查看Mike Hillyer撰写的关于Managing Heirarchial Data的优秀文章。
它解释了一个很好的方法,不仅可以构建数据,还可以查询和操作它,包括邻接列表模型和嵌套集模型之间的一些差异。
最后,我意识到这篇文章没有明确回答你直接在SQL中生成这些结果的要求。
Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2
如果没有昂贵的循环或非常难以维护的查询,您可能无法在任何体面的方式上找到很好的阅读。
通常这是在应用程序级别上完成的,因为通常这些语言更适合它(当您可以查询数据时,您可以生成深度值,这使得循环非常容易)。
答案 1 :(得分:0)
接下来的查询怎么样?
SELECT
GROUP_CONCAT(parent.name SEPARATOR '/') as parent_name
FROM category AS node,
category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.lft;
将返回请求的输出:
Primary
Primary > Secondary
Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2
可测试的@ http://sqlfiddle.com/#!9/4f4e97/2
如果只需要叶子节点
如果我正确阅读了原始问题,则您的预期输出应为:
Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2
通过稍微修改以下查询,也可以轻松实现此目标:
SELECT
GROUP_CONCAT(parent.name SEPARATOR '/') as parent_name
FROM category AS node,
category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.lft, node.rgt
HAVING node.lft = (node.rgt - 1)
ORDER BY node.lft;
然而,这假设您所有的叶子节点(应有的)都具有rgt = lft + 1 !!