0

示例数据库(嵌套集模型中的类别):

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 AND rgt 和 CONCAT 之外,我还很困惑,可以使用一些技巧和信息来获得所需的结果。谢谢!

SQL小提琴

4

2 回答 2

2

下面的查询呢?

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 !

测试@http ://sqlfiddle.com/#!9/57acd4 /1

于 2019-05-07T12:08:29.417 回答
0

查看Mike Hillyer 撰写的关于管理层次结构数据的优秀文章。

它解释了一种非常好的方法,不仅可以结构化数据,还可以查询和操作数据,包括邻接表模型和嵌套集模型之间的一些差异。

  • 表结构
  • 如何通过各种方式查询
    • 查找节点、路径和全树结果
  • 处理新数据的插入
  • 处理数据删除

最后,我意识到本文没有明确回答您直接在 SQL 中生成此类结果的要求。

Primary > Secondary > Tertiary
Primary > Secondary > Tertiary2

如果没有昂贵的循环或非常难以维护查询,您可能不会找到任何关于这样做的好方法的好读物。

通常这是在应用程序级别完成的,因为通常这些语言更适合它(当您可以查询数据时,您可以生成深度值,这使得这种循环非常容易做到)。

于 2014-05-13T23:25:21.670 回答