2012-02-03 116 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 2012-02-03 15:06:20

+0

@ user1154189沒問題:) – 2012-02-03 15:10:50

+0

@ user1154189,此查詢不使用'PARENT_ID'。向表中添加一行,例如:INSERT INTO @t(ID,VALUE,PARENT_ID,LEVEL_NO)VALUES(8,NULL,2,3)'並檢查它... – 2012-02-03 15:18:42

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

6和7的ID值應該是25000,不幸的是這個解決方案給出的是20000。也許有一種方法來調整它。 – Marie 2012-02-03 15:05:59

+0

更新了答案..看看。 – Arion 2012-02-03 15:24:04

+0

看起來不錯!這更好,因爲我的初始表是使用CTE構建的,我會嘗試使用它來使用此解決方案 – Marie 2012-02-03 16:03:12

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