सभी बच्चों के लिए कुल खोजने के लिए पुनरावर्ती CTE


16

यहां एक असेंबली ट्री है जिसे मैं नीचे अपेक्षित परिणामों के साथ एक पुनरावर्ती T-SQLक्वेरी (संभवतः CTE) का उपयोग करके खोजना चाहता हूं । मैं किसी भी भाग को दिए गए प्रति विधानसभा कुल राशि जानना चाहता हूं।

मतलब अगर मैं 'रिवेट ’खोजता हूं, तो मैं विधानसभा के भीतर प्रत्येक स्तर पर कुल गिनती जानना चाहता हूं, न कि केवल सीधे बच्चों की गिनती।

Assembly (id:1)
    |
    |-Rivet
    |-Rivet
    |-SubAssembly (id:2)
    |   |
    |   |-Rivet
    |   |-Bolt
    |   |-Bolt
    |   |-SubSubAssembly (id:3)
    |      |
    |      |-Rivet
    |      |-Rivet
    |
    |-SubAssembly (id:4)
       |-Rivet
       |-Bolt

    DESIRED Results
    -------
    ID, Count
    1 , 6
    2 , 3
    3 , 2
    4 , 1

वर्तमान में, मैं प्रत्यक्ष माता-पिता को प्राप्त कर सकता हूं, लेकिन जानना चाहता हूं कि मुझे इस जानकारी को ऊपर की ओर रोल करने की अनुमति देने के लिए अपने सीटीई को कैसे बढ़ाया जाए।

With DirectParents AS(
--initialization
Select InstanceID, ParentID
From Instances i 
Where i.Part = 'Rivet'

UNION ALL
--recursive execution
Select i.InstanceID, i.ParentID
From PartInstances i  INNER JOIN DirectParents p
on i.ParentID = p.InstanceID

)

select ParentID, Count(instanceid) as Totals
from DirectParents
group by InstanceID, ParentID

Results
-------
ID, Count
1 , 2
2 , 2
3 , 2
4 , 1

रचना लिपि

CREATE TABLE [dbo].[Instances] ( 
  [InstanceID] NVARCHAR (50) NOT NULL, 
  [Part] NVARCHAR (50) NOT NULL, 
  [ParentID] NVARCHAR (50) NOT NULL, );



INSERT INTO Instances 
Values 
  (1, 'Assembly', 0), 
  (50, 'Rivet', 1), 
  (50, 'Rivet', 1), 
  (2, 'SubAssembly', 1), 
  (50, 'Rivet', 2), 
  (51, 'Bolt', 2), 
  (51, 'Bolt', 2), 
  (3, 'SubSubAssembly', 2), 
  (50, 'Rivet', 3), 
  (50, 'Rivet', 3), 
  (4, 'SubAssembly2', 1), 
  (50, 'Rivet', 4), 
  (51, 'Bolt', 4)

जवाबों:


14

इस पुनरावर्ती CTE ( SQL Fiddle ) को आपके नमूने के साथ काम करना चाहिए:

WITH cte(ParentID) AS(
    SELECT ParentID FROM @Instances WHERE [Part] = 'Rivet'
    UNION ALL
    SELECT i.ParentID FROM cte c
    INNER JOIN @Instances i ON c.ParentID = i.InstanceID
    WHERE i.ParentID > 0
)
SELECT ParentID, count(*) 
FROM cte
GROUP BY ParentID
ORDER BY ParentID
;

उत्पादन

ParentID    Count
1           6
2           3
3           2
4           1

नोट: आपने टिप्पणियों में उल्लेख किया है कि प्रश्न में केवल एक सरलीकृत नमूना तालिका है और वास्तविक डेटा में उचित अनुक्रमित हैं और डुप्लिकेट और डेटा को पर्याप्त रूप से संभालते हैं।

उपयोग किया गया डेटा ( SQL फिडेल ):

DECLARE @Instances TABLE( 
    [InstanceID] int NOT NULL
    , [Part] NVARCHAR (50) NOT NULL
    , [ParentID] int NOT NULL
);

INSERT INTO @Instances([InstanceID], [Part], [ParentID])
VALUES 
    (1, 'Assembly', 0)
    , (50, 'Rivet', 1)
    , (50, 'Rivet', 1)
    , (2, 'SubAssembly', 1)
    , (50, 'Rivet', 2)
    , (51, 'Bolt', 2)
    , (51, 'Bolt', 2)
    , (3, 'SubSubAssembly', 2)
    , (50, 'Rivet', 3)
    , (50, 'Rivet', 3)
    , (4, 'SubAssembly2', 1)
    , (50, 'Rivet', 4)
    , (51, 'Bolt', 4)
;

शानदार जवाब धन्यवाद! क्या सभी उदाहरणों [असेंबली, रिवेट आदि] के लिए इस पुनरावृत्ति को करने के लिए एक आसान समाधान है?
ग्रीनहॉर्न

0

मुझे यकीन नहीं है कि मुझे समझ में आया है कि "राशि" और तालिका (?) के भाग और कॉलम आईडी और गणना से आपके नमूने में क्या आया है, लेकिन मैंने गणना की कि मैं आपके नमूना डेटा से क्या अनुमान लगाता हूं।

;with ins as (
select [InstanceID], [Part],[ParentID],0 lvl
from instances where ParentID=0
union all
select i.[InstanceID], i.[Part],i.[ParentID], lvl+1
from instances i 
inner join ins on i.parentid=ins.InstanceID
)
select InstanceID,part,COUNT(*) cnt
from ins
group by instanceid,part

मुझे उम्मीद है कि यह आपको कुछ विचार देगा।

अपडेट करें

मैं समझता हूं कि यह एक परीक्षा उदाहरण है, लेकिन आपका डेटा सब कुछ से शुरू होता है 1NF। संभवत: आपकी तालिका को दो में तोड़ दिया जाना चाहिए और सामान्यीकृत किया जाना चाहिए।


कोड के पहले खंड में परिणाम देखें .. जो वांछित हैं। जब 'कीलक' की खोज करते हैं, तो मैं पेड़ में किसी भी टुकड़े को दिए गए सभी rivets की कुल प्राप्त करना चाहता हूं। उदाहरण 1 उदाहरण में मुझे 6 का परिणाम देना चाहिए। इसका अर्थ है कि इसमें 6 पूर्ण rivets हैं, जो पूर्ण वृक्ष संरचना है।
मार्कोस्टेट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.