0

我已经在 MySQL 中为层次结构组列表实现了一个闭包表系统。

这些组在 table company_groups 中,列 ID 和 Name 关闭表是 company_groups_treepaths:

CREATE TABLE `company_groups` (
  `id` char(36) NOT NULL default '',
  `name` varchar(150) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `company_groups_treepaths` (
  `ParentID` char(36) NOT NULL default '',
  `ChildID` char(36) NOT NULL default '',
  `PathLength` int(11) NOT NULL default '0',
  PRIMARY KEY  (`ParentID`,`ChildID`),
  KEY `PathLength` (`PathLength`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

然后我试图从中得到一个树结构。问题是我发现的大多数解决方案都是在组 ID 上使用 group_concat,假设它是一个 INT 和 auto_increment。

但是,我使用 GUID,这使得它更难。我已经浏览了这里的其他示例,但无法真正掌握它。

例如,此查询检索正确的组,但检索错误的树:

SELECT SQL_CALC_FOUND_ROWS p.`ChildID`, p.ParentID, d.name, CONCAT(REPEAT('-', p.`PathLength`), d.`name`) as path, p.`PathLength` as depth
        FROM 
            `company_groups` AS d
        JOIN `company_groups_treepaths` AS p ON d.`id` = p.`ChildID`
        JOIN `company_groups_treepaths` AS crumbs ON crumbs.`ChildID` = p.`ChildID`

        WHERE 
            p.`ParentID` = 'aa420c70-7050-11e2-b75d-672efc30777e'
          GROUP BY d.id

ORDER BY GROUP_CONCAT(crumbs.`PathLength`)

SQL小提琴在这里:http ://sqlfiddle.com/#!2/474d4/2

该查询的正确顺序应该是(获取 Swedbank 的所有子项):

瑞典银行 (aa420c70-7050-11e2-b75d-672efc30777e)

  • hejsan (44b2b680-7f44-11e2-b04d-918fe8c8d065)
  • 东约特兰 (aa420970-7050-11e2-893a-7f63b55a76db)
    • 区域 1 (a6adc800-7050-11e2-9db0-ad8ff41db08c)
      • asd (56fd15a0-7f44-11e2-b10f-55240ef76c28)
      • hejsan3 (fc14c320-7f44-11e2-a2bb-ed51f02fd80f)
    • 在 öster (bb6b93a0-80ea-11e2-be1d-fd97d33aad97)
  • 斯莫兰 (ae5dc150-7050-11e2-9b11-c96b3591816c)
    • asdasd (534e3f00-80df-11e2-b92e-fd29e414f3fd)
    • asd (6e640160-80de-11e2-8c41-d135d36c28db)
  • hejsan2 (d95a7060-80be-11e2-8179-0b9231964800)

有人对使用 GUID 的树列表有什么好的想法吗?

该函数本身不会经常被调用,因此如果有必要解决问题,我也对子查询建议持开放态度。

4

1 回答 1

0

我恢复尝试基础知识,遵循http://karwin.blogspot.se/2010/03/rendering-trees-with-closure-tables.html上的大纲

这是最终起作用的查询:

select group_concat(n.name order by a.PathLength desc separator ' -> ') as fullpath, CONCAT(REPEAT('-', d.`PathLength`), cg.`name`) as path, d.ChildID as group_id, d.PathLength as depth, cg.name
            from company_groups_treepaths d
            join company_groups_treepaths a on (a.ChildID = d.ChildID)
            join company_groups n on (n.id = a.ParentId)
            join company_groups cg on (cg.id = d.ChildID)

            where d.ParentID = 'aa420c70-7050-11e2-b75d-672efc30777e' and cg.deleted = 0 
            group by d.ChildID
            order by fullpath
于 2013-03-04T09:01:48.630 回答