سؤال

لدي طاولة مثل هذا

childid      parentid
------------------------
1       0
2       1
3       2
4       2
5       3
6       4
7       0
8       7
9       8
10      1

إذا أعطيت طفلا على النحو 5، فإن Parentid سيكون 1 (إخراج)

إذا أعطيت طفلا باسم 9، فستكون الأبوةيد 7. (الإخراج)

أي الجذر الأبوية هو 0 والاستعلام يجب أن يتوقف هناك.

كيفية حل مثل هذا الاستعلام؟

الرجاء المساعدة.

هل كانت مفيدة؟

المحلول

أعتقد أنه يجب عليك إعادة تسمية طفلك إلى العقدة، والملب الخاص بك إلى الطفل. Naming العمود الخاص بك مربكة بعض الشيء

create table stack_overflow
(
node int, child_of int
);


insert into stack_overflow(node, child_of) values
(1,0),
(2,1),
(3,2),
(4,2),
(5,3),
(6,4),
(7,0),
(8,7),
(9,8),
(10,1);

هذا يعمل على أي RDBMS قادرة CTE:

with find_parent(parent, child_of, recentness) as
(
    select node, child_of, 0 
    from stack_overflow
    where node = 9
    union all
    select i.node, i.child_of, fp.recentness + 1
    from stack_overflow i
    join find_parent fp on i.node = fp.child_of
)
select top 1 parent from find_parent 
order by recentness desc

انتاج:

parent
7

عدل: أكثر مرونة وموادا في المستقبل:

with find_parent(node_group, parent, child_of, recentness) as
(
    select node, node, child_of, 0
    from stack_overflow
    where node in (5,9)
    union all
    select fp.node_group, i.node, i.child_of, fp.recentness + 1
    from stack_overflow i
    join find_parent fp on i.node = fp.child_of
)
select q.node_group as to_find, parent as found 
from find_parent q 
join
(
    select node_group, max(recentness) as answer
    from find_parent
    group by node_group 
) as ans on q.node_group = ans.node_group and q.recentness = ans.answer 
order by to_find    

انتاج:

to_find     found
5           1
9           7

إذا كنت تستخدم postgres., ، يمكن تقصير الرمز أعلاه إلى:

with recursive find_parent(node_group, parent, child_of, recentness) as
(
    select node, node, child_of, 0
    from stack_overflow
    where node in (5,9)
    union all
    select fp.node_group, i.node, i.child_of, fp.recentness + 1
    from stack_overflow i
    join find_parent fp on i.node = fp.child_of
)
select distinct on (node_group) node_group as to_find, parent as found 
from find_parent 
order by to_find, recentness desc

متميزة على الصخور! :-)

نصائح أخرى

إذا كان كل ما تريده هو أصل الجذر، فيمكنك استخدام هذه الوظيفة العودية:

CREATE FUNCTION test_func
(
    @ParentID int
)
RETURNS int
AS
BEGIN
    DECLARE @result int;
    DECLARE @childID int;

    SET @childID = (SELECT ChildID FROM YourTable WHERE ParentID = @ParentID)

    IF (@childID = 0)
        SET @result = @ParentID
    ELSE
        SET @result = dbo.test_func(@childID)

    RETURN @result    
END
GO

ثم في الاستعلام الرئيسي الخاص بك:

SELECT dbo.test_func(5)

تمر في 5 عائدات 1، 9 إرجاع 7 بناء على بياناتك المقدمة. إذا كنت بحاجة إلى كل PELTID الذي يرتفع هذه السلسلة، فيجب عليك استخدام CTE.

أعتقد أنك تريد استعلاما متكررا، يجب عليك استخدام تعبيرات الجدول المشترك. سأقدم لك رابطا بمثال مشابه جدا أن الشخص الذي تستخدمه.

أظن هنا هو الحل. لقد ساعدني منذ بضعة أشهر.

بسيطة من مثال الحصول على معرف الأصل مطابقة معرف الطفل معين هو:

select parentid 
from MyTable 
where childid = 5

ومع ذلك، بالنسبة للبيانات أعلاه، سيعود هذا أي سجلات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top