所有类别的父母都是CONCAT

时间:2014-05-13 21:39:39

标签: mysql sql hierarchical-data nested-sets nested-set-model

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

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之外,我还非常困难,可以使用一些有关获得所需结果的提示和信息。谢谢!

SQL Fiddle

2 个答案:

答案 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 !!

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