首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将标准Mysql表转换为嵌套表

将标准Mysql表转换为嵌套表
EN

Stack Overflow用户
提问于 2011-05-15 23:18:19
回答 1查看 796关注 0票数 0

像这样转换MySQL表最干净的方法是什么:

代码语言:javascript
复制
     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

添加到像这样的嵌套表:

代码语言:javascript
复制
     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

我精确地说,它需要独立于深度(max = 20个级别)和项目数量(超过1.000个项目)。

任何帮助都将不胜感激。

诚挚的问候。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-15 23:27:59

前面有一个问题Here

如果有人在php中执行此操作,您可能会从中获取逻辑以获得所需的解决方案。

我在一个糟糕的网站上发现了这一点,SQL只有一行,所以它需要一些格式化。我已经很好地保留了样例,所有的功劳都应该归功于神奇的Joe Celko,他多年来一直在撰写关于sql的文章。

代码语言:javascript
复制
     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

您应该能够使用它通过更改列名等方式对列表进行排序。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6009263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档