2014-09-05 90 views
2

我有HierarchyID表,並希望在子級屬性上選擇父級和子級。使用HierarchyID選擇SQL Server中的父級和子級

這裏的表:

CREATE TABLE #BOMTbl 
(
    ItemNo HIERARCHYID NOT NULL, 
    Lvl AS ItemNo.GetLevel() PERSISTED, 
    MatID VARCHAR(25) NULL, 
    CONSTRAINT PK_#BOMTbl PRIMARY KEY NONCLUSTERED(ItemNo) 
); 

insert into #BOMTbl (ItemNo,MatID) values 
('/1/',''), 
('/1/1/',''), 
('/1/1/1/','MA-A'), 
('/1/1/2/','MA-A'), 
('/1/1/3/','MA-B'), 
('/1/2/',''), 
('/1/2/1/','MA-B'), 
('/1/2/2/','MA-B'), 
('/1/3/',''), 
('/1/3/1/','PW-A'), 
('/1/3/2/','PW-A'), 
('/1/4/',''), 
('/1/4/1/','PW-B'), 
('/1/4/2/','PW-B'), 
('/1/5/','0001'), 
('/1/6/','0001'), 
('/1/7/','0002'), 
('/1/8/','0003') 

我想這樣的結果來選擇表:

ItemNo ItemID Lvl MatID 
0x5AC0 /1/1/ 2 
0x5AD6 /1/1/1/ 3 MA-A 
0x5ADA /1/1/2/ 3 MA-A 
0x5B40 /1/2/ 2 
0x5ADE /1/1/3/ 3 MA-B 
0x5B56 /1/2/1/ 3 MA-B 
0x5B5A /1/2/2/ 3 MA-B 
+0

是這個結果來自於所有的孩子一樣材質ID 'MA%'? – 2014-09-05 02:37:58

回答

0
select ItemNo, ItemNo.ToString() AS ItemID, Lvl, MatID from BOMTbl p 
WHERE exists 
(select * from BOMTbl c 
where c.MatID like 'MA%' 
and (c.ItemNo.GetAncestor(1) = p.ItemNo 
     or c.ItemNo.GetAncestor(0) = p.ItemNo)) 

SQLFiddle

+0

嗨Chang,感謝您的代碼。這是簡單的:)。你能否向我推薦關於HierarchyID查詢的書或文章。 – user3335691 2014-09-05 03:02:31

+0

@ user3335691搜索SO中的「HierarchyID」。用sqlfiddle測試這些情況。 – 2014-09-05 03:12:26

0

將下面的查詢幫助嗎?

select ItemNo, ItemNo.ToString() AS ItemID, Lvl, MatID from #BOMTbl 
WHERE ItemNo.IsDescendantOf('/1/1/') = 1 
UNION 
select ItemNo, ItemNo.ToString() AS ItemID, Lvl, MatID from #BOMTbl 
WHERE ItemNo.IsDescendantOf('/1/2/') = 1 
+0

@ zhoingxiao37:謝謝你的回覆。我按照你的代碼進行聯合兩個查詢,結果是正確的:)。 : 選擇貨號,itemno.ToString()作爲項ID,LVL,材質ID 從#BOMTbl 其中材質ID LIKE '%MA' 工會 選擇貨號,ItemNo.ToString()作爲項ID,LVL,材質ID 從#BOMTbl 其中貨號在( 選擇貨號.GetAncestor(貨號.GetLevel() - 。(從#BOMTbl 選擇#BOMTbl MAX(LVL-1)其中,材質ID LIKE '%MA'))的ToString() 其中材質ID LIKE' MA%' ) – user3335691 2014-09-05 02:43:51

0

我想出了:

with cte as (
    select * 
    from #BOMTbl 
    where MatId like 'MA%' 
) 
select * 
from cte as child 
union 
select parent.* 
from cte as child 
join #BOMTbl as parent 
    on child.ItemNo.GetAncestor(1) = parent.ItemNo 
+0

我認爲使用左連接而不是工會應該更有效率。 – 2014-09-05 13:13:53

+0

以什麼方式?具體而言,使用左連接的特定*查詢是否會建議您比我在此處「更高效」?我沒有防守,但你不能說左邊的連接總是比工會更有效率。您所能做的就是說,根據數據的情況(結構,質量和數量),具體查詢將比另一個特定查詢更有效。 – 2014-09-05 14:40:03

+1

對不起!只有在這種情況下,我的意思是,'從BOMTbl選擇不同的父。* 父 左加入CTE爲孩子 上child.ItemNo.GetAncestor(1)= parent.ItemNo 或child.ItemNo.GetAncestor(0)=父.ItemNo where child.itemno is not null'將通過減少一個表掃描來達到相同的結果。 – 2014-09-05 15:06:35