這個答案已經完全重寫。在任何情況下,原文並不完全適用
我必須更改CTE以表示每個單元的完整單元層次結構作爲可能的根(頂部單元)。它允許每個單元具有多個孩子的真實層次結構。
我擴大了樣本數據在此SQL Fiddle有分配給兩個單元11和12這正確返回正確的行爲每3名球員,對於一個單位在一定程度之下單元1.
發揮球員
「根」單元ID和播放器ID列表便利地位於底部最外面的WHERE子句中,從而可以根據需要輕鬆更改ID。
with UnitCTE as (
select u.UnitID,
u.Designation UnitDesignation,
u.ParentUnitID as ParentUnitID,
p.Designation as ParentUnitDesignation,
u.UnitID TopUnitID,
u.Designation TopUnitDesignation,
1 as TeamLevel
from Unit u
left outer join Unit p
on u.ParentUnitId = p.UnitID
union all
select t.UnitID,
t.Designation UnitDesignation,
c.UnitID as ParentUnitID,
c.UnitDesignation as ParentUnitDesignation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
)
select p.PlayerID,
p.Designation,
t1.*
from UnitCTE t1
join UnitCTE t2
on t2.TopUnitID = t1.UnitID
and t2.TopUnitID = t1.TopUnitID
join Player p
on p.UnitID = t2.UnitID
where t1.ParentUnitID = 1
and playerID in (1,2,3,4,5,6)
這裏是具有嵌入在CTE單元ID標準略微優化版本。該CTE只計算上紮根所在單位父ID是所選擇的設備ID(1在這種情況下)層次
with UnitCTE as (
select u.UnitID,
u.Designation UnitDesignation,
u.ParentUnitID as ParentUnitID,
p.Designation as ParentUnitDesignation,
u.UnitID TopUnitID,
u.Designation TopUnitDesignation,
1 as TeamLevel
from Unit u
left outer join Unit p
on u.ParentUnitId = p.UnitID
where u.ParentUnitID = 1
union all
select t.UnitID,
t.Designation UnitDesignation,
c.UnitID as ParentUnitID,
c.UnitDesignation as ParentUnitDesignation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
)
select p.PlayerID,
p.Designation,
t1.*
from UnitCTE t1
join UnitCTE t2
on t2.TopUnitID = t1.UnitID
join Player p
on p.UnitID = t2.UnitID
where playerID in (1,2,3,4,5,6)
這是我原來的答覆。它只適用於單位層次結構限制爲每個單元只允許一個孩子的情況。在這個問題的SQL小提琴例子有3個孩子1號機組,因此,如果對運行1號機組
這裏是一個SQL Fiddle演示該問題它錯誤地返回多行的玩家3,5和6。
with UnitCTE as
select UnitID,
Designation UnitDesignation,
ParentUnitID as ParentUnitID,
cast(null as varchar(50)) as ParentUnitDesignation,
UnitID TopUnitID,
Designation TopUnitDesignation,
1 as TeamLevel
from Unit
where ParentUnitID is null
union all
select t.UnitID,
t.Designation UnitDesignation,
c.UnitID,
c.UnitDesignation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
)
select p.PlayerID,
p.Designation,
t2.*
from Player p
join UnitCTE t1
on p.UnitID = t1.UnitID
join UnitCTE t2
on t2.TopUnitID = t1.TopUnitID
and t1.TeamLevel >= t2.TeamLevel
join UnitCTE t3
on t3.TopUnitID = t1.TopUnitID
and t2.TeamLevel = t3.TeamLevel+1
where t3.UnitID = 2
and playerID in (1,2,3,4)
這是你以後:http://sqlfiddle.com/#!3/78965/5 – 2012-07-16 21:35:33
維傑,給你想要作爲表的結果!你的問題是無稽之談。你說*「我希望能夠讓每個玩家都在」TeamB「下,但是」Player4「的頂級單位應該是」TeamC「。爲了做到這一點,我想通過的是PlayerID和ID 「TeamB」,所以我的意思是「讓TeamB下的所有球員和頂級單位,然後濾除除Player4以外的所有球員」。*對不起,但這根本沒有意義,並且與數據和結果無關SQLFiddle。 – 2012-07-16 21:50:09
@SteveKass - 我在這個問題中增加了更多的信息,似乎有點苛刻,把它稱爲廢話,但是我能理解我失去了你的位置!希望我的編輯更有意義,如果不是請解釋哪一部分希望它不是全部!)在具體沒有意義,我會盡我所能進一步解釋。 – Faraday 2012-07-16 22:12:34