как присвоить родительские ИД ? (дерево)

Snark
Дата: 10.10.2003 04:24:10
исходная таблица

use test
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Upr]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Upr]
GO

CREATE TABLE [Upr]([ID] [int] NOT NULL ,[lvl] [int] NOT NULL ,[pos] [int] NOT NULL, [ParentID] [int] NOT NULL) ON [PRIMARY]

INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(11,0, 1, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(12,1, 2, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(13,1, 3, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(14,1, 4, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(15,2, 5, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(16,0, 6, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(17,1, 7, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(18,2, 8, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(19,2, 9, 0)
INSERT INTO Upr (ID, lvl, pos, ParentID) VALUES(20,3, 10,0)


Каждая запись может иметь родителя, в таком случае ParentID этой записи имеет значение ID другой записи из этой же таблицы (классическое дерево)
Исходно родительские ID (ParentID) не присвоены

Необходимо присвоить родительский ParentID к каждой записи основываясь на том что каждый ребенок ниже на один уровень своего родителя и нумерация всех
записей (колонка [pos]) сквозная и непрерывная в возрастаюшем порядке

после апдейта должен получится такой результат :


ID lvl pos ParentID
----------- ----------- ----------- -----------

11 0 1 0
12 1 2 11
13 1 3 11
14 1 4 11
15 2 5 14
16 0 6 0
17 1 7 16
18 2 8 17
19 2 9 17
20 3 10 19
Snark
Дата: 10.10.2003 04:41:13
думаю что надо копать в этом направлении .. пока только не понимаю как убрать "лишних" родителей для записей с одинаковыми ID

SELECT Ch.ID AS Ch_ID, Ch.lvl AS Ch_lvl, Ch.pos AS Ch_pos,
Pr.ID AS Pr_ID, Pr.lvl AS Pr_lvl, Pr.pos As Pr_pos
FROM Upr Ch
Inner JOIN Upr Pr ON (Ch.lvl = Pr.lvl+1) AND (Ch.pos > Pr.pos)
order by Ch.pos
brahew
Дата: 10.10.2003 04:55:38
update Upr set ParentID = (select top 1 ID from Upr u2 where Upr.lvl=u2.lvl+1 and Upr.ID>u2.ID order by ID desc) where lvl<>0

вроде работает
Snark
Дата: 10.10.2003 06:44:48
спасибо, а как нибудь развернуть с INNER JOIN нельзя ? мне кажется, тогда будет еще быстрее работать
brahew
Дата: 10.10.2003 07:06:01
Ответ может быть один(мое мнение) - кому то удобней с Inner работать, а кому то удобней так.
Snark
Дата: 10.10.2003 07:22:37
Действительно, работает правильно и эффективно, спасибо еще раз.
Я согласен, использование INNER JOIN, это, зачастую, вопрос личного предпочтения.
Вопрос собственно в том, нельзя ли это сделать без вложенного запроса, тогда, может быть, весь запрос будет работать еще быстрее.