Если вы используете SQL Server 2005 или SQL Server 2008, то вы можете использовать рекурсивное CTE (общее табличное выражение). книга онлайн-статьи довольно проста, но вот как вы можете сделать это с помощью своего кода.
- Создать временную таблицу и вставить значения
CREATE TABLE dbo.ctetest (первичный ключ childid int не нулевой, parentid int null, нулевой уровень int);
INSERT INTO dbo.ctetest (childid, parentid) SELECT 1, NULL;
INSERT INTO dbo.ctetest (childid, parentid) SELECT 2, 1;
INSERT INTO dbo.ctetest (childid, parentid) SELECT 3, 1;
INSERT INTO dbo.ctetest (childid, parentid) ВЫБРАТЬ 4, 2;
INSERT INTO dbo.ctetest (childid, parentid) SELECT 5, 2;
INSERT INTO dbo.ctetest (childid, parentid) ВЫБРАТЬ 6, 3;
INSERT INTO dbo.ctetest (childid, parentid) ВЫБРАТЬ 7, 2;
INSERT INTO dbo.ctetest (childid, parentid) SELECT 8, 5;
INSERT INTO dbo.ctetest (childid, parentid) SELECT 9, 4;
INSERT INTO dbo.ctetest (childid, parentid) SELECT 10, 6;
INSERT INTO dbo.ctetest (childid, parentid) ВЫБРАТЬ 11, 6;
- Обновить таблицу данными об уровне из рекурсивного CTE
С рекурсивным (childid, parentid, level)
AS
(SELECT childid
, parentid
, 'level' = 0
FROM dbo.ctetest
WHERE parentid IS NULL
UNION ALL
SELECT ct.childid
, ct.parentid
, 'level' = rc.level + 1
FROM dbo.ctetest ct
JOIN recursivecte rc
ON ct.parentid = rc.childid)
ОБНОВЛЕНИЕ ct
SET level = rc.level
ОТ dbo.ctetest ct
JOIN recursivecte rc
ON ct.childid = rc.childid;
- Проверить результаты
ВЫБРАТЬ *
ОТ dbo.ctetest;
Вот результат вышеприведенного запроса:
ID ребенка Родительский уровень ID
1 NULL 0
2 1 1
3 1 1
4 2 2
5 2 2
6 3 2
7 2 2
8 5 3
9 4 3
10 6 3
11 6 3
Обратите внимание, что я тестировал приведенный выше код с использованием SQL Server 2008. Я предполагаю, что он будет работать в SQL Server 2005 с момента появления CTE в 2005 году.