Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

रिकर्सन को निश्चित स्तर तक सीमित करना - डुप्लिकेट पंक्तियां

यह उत्तर पूरी तरह से फिर से लिखा गया है। मूल सभी परिस्थितियों में काफी काम नहीं आया

मुझे प्रत्येक इकाई के लिए संभावित रूट (शीर्ष इकाई) के रूप में पूर्ण इकाई पदानुक्रम का प्रतिनिधित्व करने के लिए सीटीई को बदलना पड़ा। यह प्रति यूनिट कई बच्चों के साथ एक सच्चे पदानुक्रम की अनुमति देता है।

मैंने इस 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)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर - SQL स्क्रिप्ट के निष्पादन को रोकें या रोकें

  2. केवल उन फ़ाइलों के माध्यम से लूप कैसे करें जो एसएसआईएस पैकेज का उपयोग करके गंतव्य में मौजूद नहीं हैं?

  3. SQL सर्वर 2008 में दूसरे डेटाबेस के मानों के साथ एक डेटाबेस में अद्यतन रिकॉर्ड?

  4. एसक्यूएल सर्वर 2008 + पीसीआई अनुपालन? पीसीआई, साथ ही सममित कुंजी से संबंधित है!

  5. एसएसआईएस में दशमलव क्षेत्रों के साथ कार्य करना