【问题标题】:updating column based off of parent information根据父信息更新列
【发布时间】:2008-12-18 05:07:16
【问题描述】:

我是 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

如您所见,所有条目都有一个父级和一个级别,并且数据库以树形结构组织。有些条目的级别设置不正确,例如条目 ID #8。 8 的父级是 5,ID 5 的级别是 2,所以级别 8 应该是 3 而不是 4。我的表中有许多不正确的级别值,我不知道如何解决这个问题。到目前为止,我有这个:

更新我的表
SET 级别=级别-1
来自我的表
在哪里???;

我不确定如何填写 WHERE 部分,或者这是否是最好的方法。任何建议都将不胜感激。

【问题讨论】:

  • 我担心我给你的任何建议都会很危险,因为我不知道你想要完成什么。如果你给出了表格应该是什么样子的一些指示?
  • 您可以使用游标来处理更新,但会很麻烦。首先要做的是修复最初导致此问题的部分。

标签: sql-server


【解决方案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

【讨论】:

    【解决方案2】:

    如果您使用的是 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)

    作为

    (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 级别 = rc.level

    来自 dbo.ctetest ct

    加入递归函数

    ON ct.childid = rc.childid;
    

    -- 验证结果

    选择 *

    来自 dbo.ctetest;

    这是上述查询的输出:

    子 ID 父 ID 级别

    1 空 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 年推出的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 2022-07-06
      • 2022-10-23
      • 1970-01-01
      相关资源
      最近更新 更多