修复破碎的嵌套集

时间:2009-10-05 18:06:26

标签: php mysql

我必须通过脚本或sql修复损坏的嵌套集链。该表包含左侧和右侧值列,但没有父ID列。 我能够计算嵌套集中每个节点的级别。左右值存在差距。计算级别的结构是有效的。 有人知道通过SQL弥补差距的解决方案吗? (MySQL)

这些建议都不适合我的问题,但感谢您的参与。

我为我制定了一个解决方案:  1.第一步计算父ID并转换为邻接列表  2.使用Joe Celko的方法将邻接列表转换为嵌套集  3.更新旧的左右值

3 个答案:

答案 0 :(得分:1)

我只会从您拥有的左右值生成一个parent_id列,然后重新生成左右值。

如果您不想修改当前表,您甚至可以在临时表中执行此操作。

答案 1 :(得分:1)

节点(c)的每个祖先具有较小的left和较大的right值。并且直接父(p)是具有最大left值的那组(祖先)中的那个。

E.g。

CREATE TABLE nested (
  id int AUTO_INCREMENT,
  name varchar(16),
  parentid int DEFAULT 0,
  lft int(11),
  rgt int(11),
  PRIMARY KEY (id)
)

INSERT INTO
    nested (name, parentid, lft, rgt)
VALUES
    ('1'      ,0,1,20),
    ('1.1'    ,0,2,9),
    ('1.1.1'  ,0,3,4),
    ('1.1.2'  ,0,5,6),
    ('1.1.3'  ,0,7,8),
    ('1.2'    ,0,10,19),
    ('1.2.1'  ,0,11,14),
    ('1.2.1.1',0,12,13),
    ('1.2.2'  ,0,15,16),
    ('1.2.3'  ,0,17,18)

SELECT
  p.id as pid, p.name as pname,
  c.id as cid, c.name as cname  
FROM
  nested as c
LEFT JOIN
  nested as p
ON
  p.lft=(
    SELECT
      MAX(lft)
    FROM
      nested AS l
    WHERE
      c.lft > l.lft
      AND c.lft < l.rgt
  )

返回

pid    pname    cid    cname
NULL   NULL     1      1
1      1        2      1.1
2      1.1      3      1.1.1
2      1.1      4      1.1.2
2      1.1      5      1.1.3
1      1        6      1.2
6      1.2      7      1.2.1
7      1.2.1    8      1.2.1.1
6      1.2      9      1.2.2
6      1.2      10     1.2.3

答案 2 :(得分:0)

嵌套集中有4到5种不完整的案例可以完全修复(如果按正确的顺序完成)。 Snaggle很容易通过简单的触发器来检查,看看左边是不是> =右边。通过按此顺序修复嵌套集,我获得了最佳结果。一旦问题被分解如下,SQL本身并不困难。

  • 十字架(1:4 3:6)或(1:2 2:3)
  • Under / Over(1:4 1:3)OR(1:4 2:4)
  • 差距(2:3 5:6 1:7)或(2:4 5:6 1:7)
  • Snaggle(2:1 4:2)或(1:1)