根据父信息更新列

时间:2008-12-18 05:07:17

标签: sql-server

我是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 个答案:

答案 0 :(得分:1)

这将显示有问题的行。

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

答案 1 :(得分:0)

如果您使用的是SQL Server 2005或SQL Server 2008,则可以使用递归CTE(公用表表达式)。 books online article非常简单,但您可以使用代码完成此操作。

- 创建临时表并插入值

CREATE TABLE dbo.ctetest(childid int primary key not null,parentid int null,level int null);

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)SELECT 4,2;

INSERT INTO dbo.ctetest(childid,parentid)SELECT 5,2;

INSERT INTO dbo.ctetest(childid,parentid)SELECT 6,3;

INSERT INTO dbo.ctetest(childid,parentid)SELECT 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)SELECT 11,6;

- 使用递归CTE的级别数据更新表

WITH recursivecte(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

FROM dbo.ctetest ct

JOIN recursivecte rc

ON ct.childid = rc.childid;

- 验证结果

SELECT *

FROM dbo.ctetest;

以下是上述查询的输出:

子ID 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年推出的。