यह उत्तर पूरी तरह से फिर से लिखा गया है। मूल सभी परिस्थितियों में काफी काम नहीं आया
मुझे प्रत्येक इकाई के लिए संभावित रूट (शीर्ष इकाई) के रूप में पूर्ण इकाई पदानुक्रम का प्रतिनिधित्व करने के लिए सीटीई को बदलना पड़ा। यह प्रति यूनिट कई बच्चों के साथ एक सच्चे पदानुक्रम की अनुमति देता है।
मैंने इस SQL Fiddle में नमूना डेटा बढ़ाया है यूनिट 11 और 12 दोनों के लिए एक खिलाड़ी को असाइन करने के लिए। यह यूनिट 1 के नीचे किसी स्तर पर एक यूनिट के लिए खेलने वाले 3 खिलाड़ियों में से प्रत्येक के लिए सही पंक्ति को ठीक से लौटाता है।
"रूट" यूनिट आईडी और प्लेयर आईडी की सूची सबसे बाहरी WHERE क्लॉज में सुविधाजनक रूप से सबसे नीचे है, जिससे आईडी को आवश्यकतानुसार बदलना आसान हो जाता है।
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)
सीटीई में एम्बेडेड यूनिट आईडी मानदंड वाले थोड़ा अनुकूलित संस्करण यहां दिया गया है। सीटीई केवल उन इकाइयों पर आधारित पदानुक्रमों की गणना करता है जहां मूल आईडी चुनी गई इकाई आईडी है (इस मामले में 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 Fiddle उदाहरण में यूनिट 1 के लिए 3 बच्चे हैं, इसलिए यह यूनिट 1 के विरुद्ध चलाए जाने पर प्लेयर्स 3, 5 और 6 के लिए कई पंक्तियों को गलत तरीके से लौटाता है।
यहां एक SQL Fiddle है जो समस्या को प्रदर्शित करता है।
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)