2017-06-01 41 views
3

如何知道所有可能的父級和子行鍼對特定的ID?想要知道所有可能的父母和子行對特定的ID?

例如有如下表:

MyTable的:

----------------------------------------------------- 
| Id | PId | Description    | 
----------------------------------------------------- 
| 1 | NULL | A is Parent    | 
| 2 |  1  | B is Child of A   | 
| 3 |  2  | C is Child of B   | 
| 4 | NULL | D is Parent    | 
| 5 | NULL | E is Parent    | 
| 6 |  5  | F is Child of E   | 
----------------------------------------------------- 

想知道的所有可能的父母和孩子,當通spesific ID

例如

CASE-01:

@ MyLookupId = 2 OR @ MyLookupId = 1 OR @ MyLookupId = 3一個從他們然後結果應該是,

------- 
| Id | 
------- 
| 1 | 
| 2 | 
| 3 | 
------- 

CASE-02:

@ MyLookupId = 4然後結果應該是,

------- 
| Id | 
------- 
| 4 | 
------- 

CASE-03:

@ MyLookupId = 6然後結果應該是,

------- 
| Id | 
------- 
| 5 | 
| 6 | 
------- 

下面是表的SQL:

IF OBJECT_ID('tempdb.dbo.#MyTable', 'U') IS NOT NULL DROP TABLE #MyTable; 
SELECT * INTO #MyTable FROM (
    SELECT (1)Id, (NULL)PId, ('A IS Parent')Description UNION ALL 
    SELECT (2)Id, (1)PId, ('B IS Child of A')Description UNION ALL 
    SELECT (3)Id, (2)PId, ('C IS Child of B')Description UNION ALL 
    SELECT (4)Id, (NULL)PId, ('D IS Parent')Description UNION ALL 
    SELECT (5)Id, (NULL)PId, ('E IS Parent')Description UNION ALL 
    SELECT (6)Id, (5)PId, ('F IS Child of E')Description) AS tmp 

SELECT * FROM #MyTable 
+0

哪裏有是「1名兒童6'說'7'。現在lookupid = 5,你也想要這個孩子嗎? – Utsav

+0

5是父母,6是5的孩子,所以是應該在結果。 – Haseeb

+0

使用CTE來確定位置......這裏有許多CTE案例或基本的CTE – maSTAShuFu

回答

1

通過TRIV作品給出的答案,但需要每次計算源表的整個層次結構e查詢運行,可能無法在較大規模下執行。

更窄的辦法是找父母與子女的記錄,只有涉及到ID您正在搜索:

declare @t table(ID int, PID int); 
insert into @t values(1,null),(2,1),(3,2),(4,null),(5,null),(6,5); 

declare @ID int = 2; 

with c as 
(
    select ID 
      ,PID 
    from @t 
    where ID = @ID 

    union all 

    select t.ID 
      ,t.PID 
    from @t t 
     join c 
      on(t.PID = c.ID) 
) 
,p as 
(
    select ID 
      ,PID 
    from @t 
    where ID = @ID 

    union all 

    select t.ID 
      ,t.PID 
    from @t t 
     join p 
      on(t.ID = p.PID) 
) 
select ID 
from p 

union all 

select ID 
from c 
where c.ID <> @ID 
order by ID; 

輸出:

ID 
```` 
1 
2 
3 
+0

快速比較TriV sql +1 – Haseeb

2

你可以使用recursive cte

-- temp returns full tree of each rootId (parentid = null) 
;WITH temp AS 
(
    SELECT sd.Id, sd.PId, sd.Id AS RootId 
    FROM #MyTable sd 
    WHERE sd.PId IS NULL 

    UNION ALL 

    SELECT sd.Id, sd.PId, t.RootId 
    FROM temp t 
    INNER JOIN #MyTable sd ON t.Id = sd.PId 
) 

SELECT t2.Id 
FROM temp t 
INNER JOIN temp t2 ON t2.RootId = t.RootId 
WHERE t.Id = @Id 
OPTION (MAXRECURSION 0) 

演示鏈接:http://rextester.com/RAITMT72805

+0

謝謝!效果很好 – Haseeb

+0

@Haseeb一定要測試整個數據集的性能,因爲它需要一個完整的樹計算 - 包括你沒有搜索到的'ID'值 - 才能刪除相關結果。跨越大量值的這種冗餘遞歸量可能具有顯着的不必要開銷。 – iamdave

+0

@iamdave謝謝你的建議我需要將它應用於大量的行,所以讓我檢查一下,並將在這裏發表我的意見......也感謝你的偉大答案! – Haseeb

相關問題