2012-02-03 2 views
2

행을 검색 할 때 부모로부터 자식으로 값을 복사하는 방법을 T-SQL (저장 프로 시저에서)을 통해 습득하려고합니다.SELECT는 계층 구조에서 부모로부터 값을 상속합니다.

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 | VALUE | LEVEL_NO | 
+----+-------+----------+ 
| 1 | 10000 |  1 | 
| 2 | 10000 |  2 | 
| 3 | 10000 |  3 | 
| 4 | 20000 |  1 | 
| 5 | 20000 |  2 | 
| 6 | 25000 |  3 | 
| 7 | 25000 |  4 | 
+----+-------+----------+ 

C 커서를 사용하지 않고도이 작업을 수행 할 수 있습니다 (SQL Server 2005에서도 실행해야 함)?

답변

-1

한 가지 방법은 그것을 할 수 있습니다 :

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 
+0

완벽하게 작동합니다! 감사합니다 – Marie

+0

@ user1154189 아무 문제가 없습니다 :) –

+0

@ user1154189,이 쿼리는'PARENT_ID'를 사용하지 않습니다. INSERT INTO @t (ID, VALUE, PARENT_ID, LEVEL_NO) VALUES (8, NULL, 2, 3)'와 같은 테이블에 행을 하나 더 추가하고 확인하십시오 ... –

0

아마 이런 식으로 뭔가 :

;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 
+0

ID 6과 ID의 값이 25000이어야합니다.이 솔루션은 불행하게도 대신 20000을 제공합니다. 어쩌면 그것을 조정할 수있는 방법이 있습니다. – Marie

+0

답변을 업데이트했습니다. – Arion

+0

좋아 보인다! 이것은 CTE를 사용하여 초기 테이블을 구축 한 것보다 훨씬 뛰어납니다.이 솔루션을 사용하기 위해이 솔루션을 사용하려고합니다. – Marie

3

사용 :

;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