2014-05-13 7 views
9

के साथ अभिभावक बाल संबंध के लिए सीटीई मेरे पास एक अभिभावक बाल संबंध तालिका है जैसा कि नीचे दिखाया गया है। मैं माता-पिता या बच्चे आईडी के लिए सभी पूर्वजों और माता-पिता और गहराई से संभव होने पर सभी रिकॉर्ड्स पुनर्प्राप्त करना चाहता हूं। उदाहरण के लिए मैं डी के परिवार को ढूंढना चाहता हूं, यह पहले 14 पंक्तियों को वापस कर देगा क्योंकि सभी एक ही परिवार के हैं। ऐसे परिवार के कई सेट हो सकते हैं। मैं एक सदस्य से पूछना चाहता हूं और पूरे परिवार के रिकॉर्ड प्राप्त करना चाहता हूं। क्या सीटीई का उपयोग करके इसे कार्यान्वित करना संभव है? टेबल रिकॉर्ड के अनुसार पारिवारिक संरचना:एकाधिक माता-पिता

     A 
        /\ 
        B C G J 
       / \/\/\ 
       M D  E H K 
      /\/   \/\ 
      N F    I L 


       R 
       | 
       S U 
        \/
        T 

कृपया मदद करें। मेज की तरह है:

Parent Child 
    ------ ------ 
    A   B 
    A   C 
    B   D 
    D   F 
    M   F 
    M   N 
    C   E 
    G   E 
    G   H 
    J   H 
    J   K 
    H   I 
    K   I 
    K   L 
    R   S 
    S   T 
    U   T 

धन्यवाद,

हिमाद्री

+0

ट्रेल्स मैं जानता हूँ कि यह एक पुनरावर्ती पूछताछ का उपयोग करके सभी प्रत्यक्ष सन्तान को पुनः प्राप्त करना संभव है। मैं यह देखने के लिए उत्सुक हूं कि किसी के पास मनमाना माता-पिता/बच्चे के रिश्तों के पूर्ण ग्राफ के लिए समाधान है या नहीं। –

+0

चक्रीय ग्राफ :) मुझे हाल ही में इस प्रकृति की एक समस्या का सामना करना पड़ा है। मैं 'आरसीटीई' प्रगति के रूप में कुशलता से दौरे \ ट्रैवर्सल इतिहास (और इसे पूछताछ) रिकॉर्डिंग में फंस गया। यहां सुझाए गए 'WHILE' लूप का उपयोग करके लैंडेड: http://hansolav.net/sql/graphs.html - इस पोस्ट पर मेरी आंखें रखेगी ताकि यह देखने के लिए कि इसमें क्या आता है। – MarkD

उत्तर

1

मैं एक समाधान मिल गया। लेकिन मैंने कुछ समय लूप में सीटीई का उपयोग किया। अगर किसी के पास कोई अन्य समाधान है तो कृपया सुझाव दें। जैसा कि मैंने उपर्युक्त तालिका का उल्लेख किया है जिसमें परिवार के रिकॉर्ड हैं या आप ग्राफ कह सकते हैं। आइए इसे tbl_ParentChild के रूप में नाम दें।

Declare @Child varchar(10), @RowsEffected int 
Set @Child='D'-----It is the member whose family we want to find 

CREATE Table #PrntChld (Parent varchar(10),Child varchar(10)) 
Insert Into #PrntChld 
Select Parent,Child from tbl_ParentChild MF 
Where [email protected] or [email protected] 

Select @RowsEffected=Count(*) from #PrntChld 

While @RowsEffected>0 
BEGIN 
    ;WITH Prnt(Parent,Child) 
     AS 
     (Select M.Parent,M.Child from tbl_ParentChild M 
      Inner Join #PrntChld F On F.Child=M.Child 
      UNION ALL 
      SELECT e.Parent,e.Child  
       FROM tbl_ParentChild AS E 
       INNER JOIN Prnt AS M     
        ON E.Child = M.Parent   
     ), 
     PrntChld(Parent,Child) 
     AS 
     (Select M.Parent,M.Child from tbl_ParentChild M 
      Inner Join (Select * from Prnt union Select * from #PrntChld) F On M.Parent=F.Parent 
      UNION ALL 
      SELECT e.Parent,e.Child  
       FROM tbl_ParentChild AS E 
       INNER JOIN PrntChld AS M     
        ON M.Child = E.Parent   
     ) 

    Insert Into #PrntChld 
    Select distinct MF.* from PrntChld MF 
    Left Join #PrntChld T On T.Child =MF.Child and T.Parent = MF.Parent  
    where T.Child is null 
    Select @[email protected]@ROWCOUNT 

END 

Select * from #PrntChld 
drop table #PrntChld 
2

मैं प्रत्यावर्तन की एक स्ट्रिंग सीमक के साथ अपने समाधान पोस्ट करेंगे:

यहाँ मेरी कोड है। मुझे आश्चर्य हुआ कि क्या यह एक अच्छा ग्राफ के लिए प्रदर्शन के तरीके से अच्छा है, लेकिन मुझे लगता है कि यह सब के बाद इतना बुरा नहीं है। असल में मैं दोबारा संबंधों को संसाधित कर रहा हूं, "पथ" को रिकॉर्ड करना जो मुझे प्रत्येक चरण में ले गया, और पथ की जांच कर रहा था ताकि जब मैं एक परिपत्र संबंध मारा तो मैं रुक सकता हूं।

जो कोई यह कोशिश करना चाहता है के लिए, मैं बना सकते हैं और तालिका के भरने पोस्टिंग कर रहा हूँ:

declare @let char = 'D'; 
with cte as 
(
    --get the node itself if it exists in the table at all 
    select 
     top 1 @let as letter, '' as rec_path 
    from 
     nodes 
    where 
     c = @let or p = @let 

    union all 
    -- get the direct relations of the node as a starting point 
    select 
     case when c = @let then p else c end as letter, 
     cast(@let as varchar(max)) as rec_path 
    from 
     nodes 
    where 
     c = @let or p = @let 

    union all 
    -- get all of the relations recursively until you reach a node you already processed 
    select 
     case when c = cte.letter then p else c end as letter, 
     rec_path + cte.letter as rec_path 
    from 
     cte 
     join nodes on 
      (cte.letter = nodes.c and charindex(cast(nodes.p as varchar(1)), rec_path, 1) = 0 
      or (cte.letter = nodes.p and charindex(cast(nodes.c as varchar(1)), rec_path, 1) = 0)) 
) 
select 
    distinct letter 
from 
    cte 

मुझे आशा है कि यह उपयोगी होगा:

create table nodes 
(
    p char, 
    c char 
) 
insert into nodes (p, c) 
values 
    ('A', 'B'), ('A', 'C'), ('B', 'D'), ('D', 'F'), ('M', 'F'), ('M', 'N'), ('C', 'E'), 
    ('G', 'E'), ('G', 'H'), ('J', 'H'), ('J', 'K'), ('H', 'I'), ('K', 'I'), ('K', 'L'), 
    ('R', 'S'), ('S', 'T'), ('U', 'T') 

और यहाँ क्वेरी है । मुझे एहसास है कि आपके डेटा में वास्तव में अक्षर नहीं होते हैं, लेकिन यह एक स्ट्रिंग पथ या यहां तक ​​कि एक एक्सएमएल का उपयोग कर आईडी-एस के साथ भी किया जा सकता है।

0

यह समाधान केवल विश्वकोश ग्राफ के साथ काम करेगा क्योंकि चक्र चक्र टूट जाएगा यदि चक्र, डेटा सेट को आपूर्ति के रूप में ले रहा है ...

create table nodes 
(
    p char, 
    c char 
) 
insert into nodes (p, c) 
values 
    ('A', 'B'), ('A', 'C'), ('B', 'D'), ('D', 'F'), ('M', 'F'), ('M', 'N'), ('C', 'E'), 
    ('G', 'E'), ('G', 'H'), ('J', 'H'), ('J', 'K'), ('H', 'I'), ('K', 'I'), ('K', 'L'), 
    ('R', 'S'), ('S', 'T'), ('U', 'T') 

GO 

हम आगे पेड़ माता पिता प्राप्त कर सकते हैं - मूल नोड अधिक रिकॉर्ड recursing द्वारा> बच्चे

CREATE VIEW dbo.Tree 
AS 
    WITH Hierarchy(r, p, c, [Level]) 
    AS 
    (
     SELECT p AS r, 
       p, 
       c, 
       0 AS [Level] 
     FROM dbo.nodes 
     UNION ALL 
     SELECT n.p AS r, 
       t.p, 
       t.c, 
       t.[Level] + 1 
     FROM Hierarchy t 
     INNER JOIN dbo.nodes n ON n.c = t.r 
     AND n.p != t.p 
    ) 
    SELECT r, p, c, [Level] 
    FROM Hierarchy 

यह तो परिणाम

r p c Level 
A A B 0 
A A C 0 
A C E 1 
A D F 2 
A B D 1 
B D F 1 
B B D 0 
C C E 0 
D D F 0 
G G E 0 
G G H 0 
G H I 1 
H H I 0 
J H I 1 
J K L 1 
J K I 1 
J J H 0 
J J K 0 
K K I 0 
K K L 0 
M M F 0 
M M N 0 
R R S 0 
R S T 1 
S S T 0 
U U T 0 

हम तो अन्य ऐसा कर सकते हैं देता है जिस तरह से हम बच्चे से अपने माता-पिता (0)

CREATE VIEW dbo.ReverseTree 
AS 
    WITH Hierarchy(r, c, p, [Level]) 
    AS 
    (
     SELECT c AS r, 
       c, 
       p, 
       0 AS [Level] 
     FROM dbo.nodes 
     UNION ALL 
     SELECT n.c AS r, 
       t.c, 
       t.p, 
       t.[Level] + 1 
     FROM Hierarchy t 
     INNER JOIN dbo.nodes n ON n.p = t.r 
     AND n.c != t.c 
    ) 
    SELECT r, c, p, [Level] 
    FROM Hierarchy 
पर जा सकते हैं

और यह

r c p Level 
B B A 0 
C C A 0 
D D B 0 
D B A 1 
E C A 1 
E E C 0 
E E G 0 
F F D 0 
F F M 0 
F D B 1 
F B A 2 
H H G 0 
H H J 0 
I I H 0 
I I K 0 
I K J 1 
I H J 1 
I H G 1 
K K J 0 
L K J 1 
L L K 0 
N N M 0 
S S R 0 
T T S 0 
T T U 0 
T S R 1 

यह ब्रेडक्रम्ब जैसी चीजों के लिए उपयोगी है की तरह लग रहे है कि से परिणाम

संबंधित मुद्दे