2011-05-15 47 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