Sql 选择“从层次结构中的父级继承值”

Sql 选择“从层次结构中的父级继承值”,sql,sql-server,tsql,common-table-expression,Sql,Sql Server,Tsql,Common Table Expression,我试图通过T-SQL(在存储过程中)实现一种方法,在检索行时将值从父级复制到子级。以下是一些示例数据: DROP TABLE TEST_LEVELS CREATE TABLE TEST_LEVELS( ID INT NOT NULL ,VALUE INT NULL ,PARENT_ID INT NULL ,LEVEL_NO INT NOT NULL ) INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_N

我试图通过T-SQL(在存储过程中)实现一种方法,在检索行时将值从父级复制到子级。以下是一些示例数据:

DROP TABLE TEST_LEVELS
CREATE TABLE TEST_LEVELS(
     ID INT NOT NULL
    ,VALUE INT NULL
    ,PARENT_ID INT NULL
    ,LEVEL_NO INT NOT NULL
)

INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (1, 10000, NULL, 1)
INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (2, NULL, 1, 2)
INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (3, NULL, 2, 3)
INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (4, 20000, NULL, 1)
INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (5, NULL, 4, 2)
INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (6, 25000, 5, 3)
INSERT INTO TEST_LEVELS (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (7, NULL, 6, 4)
选择以下数据:

SELECT ID, VALUE, LEVEL_NO
FROM TEST_LEVELS
结果:

+----+-------+----------+ | ID | VALUE | LEVEL_NO | +----+-------+----------+ | 1 | 10000 | 1 | | 2 | NULL | 2 | | 3 | NULL | 3 | | 4 | 20000 | 1 | | 5 | NULL | 2 | | 6 | 25000 | 3 | | 7 | NULL | 4 | +----+-------+----------+ +----+-------+----------+ |ID |值|级别|编号| +----+-------+----------+ | 1 | 10000 | 1 | |2 |空| 2| |3 |空| 3| | 4 | 20000 | 1 | |5 |空| 2| | 6 | 25000 | 3 | |7 |空| 4| +----+-------+----------+ 但我需要这样的东西(值由父级继承):

+----+-------+----------+ |ID |值|级别|编号| +----+-------+----------+ | 1 | 10000 | 1 | | 2 | 10000 | 2 | | 3 | 10000 | 3 | | 4 | 20000 | 1 | | 5 | 20000 | 2 | | 6 | 25000 | 3 | | 7 | 25000 | 4 | +----+-------+----------+ 不使用游标(它也必须在SQL Server 2005上运行)是否可以实现此目的?

一种方法:

SELECT T.ID,
    case when T.VALUE IS NULL
    THEN (SELECT A.VALUE FROM TEST_LEVELS A WHERE A.ID = T.PARENT_ID)
    ELSE T.VALUE
    END,
    T.LEVEL_NO
FROM TEST_LEVELS T

也许是这样的:

;WITH cte_name(ID,VALUE,PARENT_ID,LEVEL_NO)
AS
(
    SELECT
        tbl.ID,
        tbl.VALUE,
        tbl.PARENT_ID,
        tbl.LEVEL_NO
    FROM
        TEST_LEVELS AS tbl
    WHERE 
        tbl.PARENT_ID IS NULL
    UNION ALL
    SELECT
        tbl.ID,
        ISNULL(tbl.VALUE,cte_name.VALUE),
        tbl.PARENT_ID,
        tbl.LEVEL_NO
    FROM
        cte_name
        JOIN TEST_LEVELS AS tbl
            ON cte_name.ID=tbl.PARENT_ID

)
SELECT
    *
FROM 
    cte_name
ORDER BY 
    ID
使用:

输出:

ID          Value       LEVEL_NO
----------- ----------- -----------
1           10000       1
2           10000       2
3           10000       3
4           20000       1
5           20000       2
6           25000       3
7           25000       4

Ids 6和Ids 7的值应为25000,不幸的是,此解决方案的值为20000。也许有办法调整一下。更新了答案。。看一看,看起来不错!这甚至更好,因为我的初始表是使用CTE构建的,我将尝试对其进行调整以使用它solution@user1154189,此查询不使用父ID。向表中再添加一行,例如:
插入@t(ID,VALUE,PARENT\u ID,LEVEL\u NO)值(8,NULL,2,3)
并检查它…ID号3为NULL,此查询仅对第一个子项有效
;with cte
as
(
    select t.ID, t.VALUE, t.PARENT_ID, t.LEVEL_NO
    from @t t
    where t.Value is not null

    union all 

    select t.ID, c.Value, t.PARENT_ID, t.LEVEL_NO
    from cte c
    join @t t on t.PARENT_ID = c.ID
    where t.Value is null
)

select c.ID, c.Value, c.LEVEL_NO
from cte c
order by c.ID
ID          Value       LEVEL_NO
----------- ----------- -----------
1           10000       1
2           10000       2
3           10000       3
4           20000       1
5           20000       2
6           25000       3
7           25000       4