2011-05-15 46 views
0

什么是转换MySQL表像这样最彻底的方法:转换一个标准的MySQL表嵌套表

 id | fullindi        | parent | rank 
--------------------------------------------------------------- 
     1 | LHUILLIER Pierre (ca 1700 - 1745)  | 0 | 0 
     9 | LHUILLIER Claude (ca 1729 - 1806)  | 1 | 1 
    10357 | LHUILLIER Joseph (ca 1730 - 1738)  | 1 | 2 
     7 | LHUILLIER François (ca 1731 - 1794) | 1 | 3 
     3 | LHUILLIER Antoine (1736 - av. 1797) | 1 | 4 
     4 | LHUILLIER Anne Marie (1737 - ____) | 1 | 5 
    4903 | LHUILLIER Dominique (1740 - ____)  | 1 | 6 
     5 | LHUILLIER Thérèse (1741 - ____)  | 1 | 7 
     8 | LHUILLIER Augustin (ca 1743 - ____) | 1 | 8 
     6 | LHUILLIER Joseph (1745 - ap. 1804) | 1 | 9 
    322 | LHUILLIER N... (1749 - ____)   | 9 | 1 
    323 | LHUILLIER Marianne (1751 - ____)  | 9 | 2 
    324 | LHUILLIER François (1752 - ____)  | 9 | 3 
    325 | LHUILLIER Augustin (1754 - av. 1810) | 9 | 4 
    326 | LHUILLIER Léopold (1757 - av. 1819) | 9 | 5 
    327 | LHUILLIER Nicolas (1758 - ____)  | 9 | 6 
    328 | LHUILLIER N... (1760 - ____)   | 9 | 7 
    329 | LHUILLIER Claude (1765 - ____)  | 9 | 8 
    4643 | LHUILLIER Jean Baptiste (1766 - 1836) | 9 | 9 
    331 | LHUILLIER Marie Jeanne (1767 - 1823) | 9 | 10 
    etc 

到嵌套表是这样的:

 id | fullindi        | posleft | posright 
-------------------------------------------------------------------- 
     1 | LHUILLIER Pierre (ca 1700 - 1745)  | 0 | 848 
     9 | LHUILLIER Claude (ca 1729 - 1806)  | 1 | 1 
    322 | LHUILLIER N... (1749 - ____)   | 2 | 3 
    323 | LHUILLIER Marianne (1751 - ____)  | 4 | 5 
    324 | LHUILLIER François (1752 - ____)  | 6 | 7 
    325 | LHUILLIER Augustin (1754 - av. 1810) | 8 | 9 
    etc 

我精确,它需要独立于深度(最多= 20个级别)和项目数量(超过1,000个项目)。

任何帮助将不胜感激。

此致敬礼。

回答

1

有前一个问题Here

如果有人做这在PHP中,你很可能取逻辑从得到你需要的解决方案。

我在一个蹩脚的网站上发现了这一点,SQL全部在一行,因此它采取了一些格式化。我已经离开了这个样本,所有的荣誉都应该归功于一直在写关于sql多年的神奇的Joe Celko。

 CREATE TABLE Tree (
    child CHAR(10) NOT NULL, 
    parent CHAR(10), 
    CONSTRAINT PK_Tree PRIMARY KEY CLUSTERED(child)) 

    -- insert the sample data for testing 

    INSERT INTO Tree(child,parent) VALUES ('Albert', NULL) 
    INSERT INTO Tree(child,parent) VALUES ('Bert', 'Albert') 
    INSERT INTO Tree(child,parent) VALUES ('Chuck', 'Albert') 
    INSERT INTO Tree(child,parent) VALUES ('Donna', 'Chuck') 
    INSERT INTO Tree(child,parent) VALUES ('Eddie', 'Chuck') 
    INSERT INTO Tree(child,parent) VALUES ('Fred', 'Chuck') 


CREATE TABLE Stack (
    StackID int IDENTITY(1,1), 
    stack_top INTEGER NOT NULL, 
    child VARCHAR(10) NOT NULL, 
    lft INTEGER NOT NULL, 
    rgt INTEGER, 
    CONSTRAINT PK_Stack PRIMARY KEY CLUSTERED(StackID)) 


    DECLARE @lft_rgt INTEGER, @stack_pointer INTEGER, @max_lft_rgt INTEGER 

    SET @max_lft_rgt = 2 * (SELECT COUNT(*) FROM Tree) 

    INSERT INTO Stack 
    SELECT 1, child, 1, @max_lft_rgt 
    FROM Tree 
    WHERE parent IS NULL 

    SET @lft_rgt = 2 

    SET @Stack_pointer = 1 

    DELETE FROM Tree WHERE parent IS NULL 

    -- The Stack is now loaded and ready to use 

    WHILE (@lft_rgt < @max_lft_rgt) 
     BEGIN 
      IF EXISTS (SELECT * FROM Stack AS S1, Tree AS T1 WHERE S1.child = T1.parent AND S1.stack_top = @stack_pointer) 
       BEGIN 
        -- push when stack_top has subordinates and set lft value 
        INSERT INTO Stack 
        SELECT (@stack_pointer + 1), 
        MIN(T1.child), 
        @lft_rgt, 
        NULL 
        FROM Stack AS S1, 
        Tree AS T1 
        WHERE S1.child = T1.parent AND S1.stack_top = @stack_pointer 

        -- remove this row from Tree 
        DELETE FROM Tree 
        WHERE child = (SELECT child FROM Stack WHERE stack_top = @stack_pointer + 1) 

        SET @stack_pointer = @stack_pointer + 1 
       END 
     -- push 
     ELSE 
      BEGIN 
       -- pop the Stack and set rgt value 
       UPDATE Stack SET rgt = @lft_rgt, stack_top = -stack_top 
       WHERE stack_top = @stack_pointer 

       SET @stack_pointer = @stack_pointer - 1 
      END 

      -- pop 
     SET @lft_rgt = @lft_rgt + 1 
    END 

你应该能够用它来整理你的列表中再次更改列名称等

这不是我的工作,再次再次感谢乔·塞科(我一直在一个很长一段时间嵌套集模型的粉丝,并有几个系统在使用它的生产)。我一直无法找到乔的博客,如果有一个(如果你在那里请评论这里,并采取所有功劳

+0

我知道这篇文章,我花了整整一天试图适应它没有成功。开始工作,但忘记了我的项目很大一部分没有理由,没有任何错误信息。 – mlh 2011-05-15 15:30:49

+0

坚持我在t-sql中找到了一个更好的方法。Howerver我只能在一个蹩脚的网站上找到它,给我一个棚我现在已经格式化了它,但是需要测试它 – 2011-05-15 15:50:24

+0

我坚持认为它是创建一个家谱树,如果我有重复条目(这在家谱中是可能的),那么你提到的帖子的代码出现了故障并给出了一个严重的错误,但是,左边的num从“4”(而不是“0”或“1”)开始,并且树的2个第一人不在嵌套中-table ...还有很多“Und已定义索引“通知存在索引。 – mlh 2011-05-15 16:02:10