обновление столбца на основе родительской информации - PullRequest
1 голос
/ 18 декабря 2008

Я новичок в SQL Server, и у меня есть вопрос о том, как лучше всего это сделать.

У меня есть таблица, которая выглядит так:

ID Родительский уровень
1 NULL 0
2 1 1
3 1 1
4 2 2
5 2 2
6 3 2
7 2 2
8 5 4
9 4 3
10 6 3
11 6 3

Как видите, все записи имеют Родителя и Уровень, а база данных организована в виде древовидной структуры. Есть некоторые записи, в которых уровень установлен неправильно, например, идентификатор записи # 8. Родитель 8 равен 5, а ID 5 имеет уровень 2, поэтому уровень 8 должен быть 3, а не 4. В моей таблице много неправильных значений уровня, и я не уверен, как это исправить. Пока у меня есть это:

ОБНОВЛЕНИЕ myTable
Уровень SET = уровень-1
ИЗ myTable
ГДЕ ???;

Я не уверен, как заполнить часть WHERE или это лучший способ сделать это. Любые предложения приветствуются.

Ответы [ 2 ]

1 голос
/ 18 декабря 2008

Это покажет вам строки, которые имеют проблемы.

select
  a.id,
  a.level,
  b.level as parentlevel
from
  tablename a
  join tablename b on a.parent = b.id
where
  a.level <> b.level+1
0 голосов
/ 18 декабря 2008

Если вы используете 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 году.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...