像这样转换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我精确地说,它需要独立于深度(max = 20个级别)和项目数量(超过1.000个项目)。
任何帮助都将不胜感激。
诚挚的问候。
发布于 2011-05-15 23:27:59
前面有一个问题Here
如果有人在php中执行此操作,您可能会从中获取逻辑以获得所需的解决方案。
我在一个糟糕的网站上发现了这一点,SQL只有一行,所以它需要一些格式化。我已经很好地保留了样例,所有的功劳都应该归功于神奇的Joe Celko,他多年来一直在撰写关于sql的文章。
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 (我一直是嵌套集合模型的粉丝,现在有几个系统在生产中使用它)。我一直无法找到乔的博客,如果有一个(如果你在那里,请在这里评论,并采取所有的功劳。
https://stackoverflow.com/questions/6009263
复制相似问题