Есть предыдущий вопрос Здесь
Если кто-то делает это в php, вы, вероятно, можете воспользоваться логикой, чтобы получить необходимое решение.
Iнашел это на дрянном веб-сайте, и SQL был в одной строке, поэтому потребовалось немного форматирования.Я оставил образец почти как есть, и вся заслуга должна быть у фантастического Джо Селко, который годами писал о 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
Вы должны быть в состоянии использовать это, чтобы отсортировать свой список поизменение имен столбцов и т. д.
Еще раз, это не моя работа, еще раз спасибо Джо Селко (я давно поклонник модели с вложенным множеством и у меня есть несколько систем в производствеиспользуй это).Мне не удалось найти блог Джо, если он есть (если вы там, пожалуйста, прокомментируйте здесь и возьмите всю сумму.