2015-11-22 57 views
4

比方說,有一個叫人有以下的列表:如何僅使用與SQL父表子關係選擇一代分層樹?

  • 爲person_id(整數)
  • parent_person_id(整數)
  • 名(爲varchar)

現在,讓我們說表正在填充,名稱值只是字母(A,B,C,D ...)。考慮到每個人的父母,我們最終會得到像下面那樣的分層樹。這些值是在格式:

爲person_id,parent_person_id,名稱

  • 1,1,A
  • 2,2,B
    • 3,2,C
      • 4,3,D
    • 5,2,E
      • 6,5,F
        • 7,6,G
        • 8,6,H

考慮在以上的結構中,A & B作爲第一代,C & E作爲第二代,D第三代210 F,第四代G & H.對於第一代元素,parent_person_id等於元素的person_id。

我需要編寫一個查詢,允許我從樹的特定代(第一,第二,第三,第四等)中選擇名稱。因此,我可以得到一個表格,其中包含特定用戶的姓名。例如:

第一代

person name | parent name 
A   | A 
B   | B 

第二代

person name | parent name 
C   | B 
E   | B 

第三代

person name | parent name 
D   | C 
F   | E 

第四代

person name | parent name 
G   | F 
H   | F 

我想通過一個參數來定義每一代應該在下面的查詢中被列爲子。

SELECT 
    child.name as 'person name', 
    parent.name as 'parent name' 
FROM 
    people as child 
JOIN 
    people as parent 
ON 
    child.parent_person_id = parent.person_id 
WHERE 
    -- I NEED HELP HERE :) 
; 

有沒有人有任何想法,我怎麼能做到這一點?歡迎任何幫助。

+0

維尼修斯,我覺得這個提問/回答可以幫助你http://stackoverflow.com/questions/5522478/sql-query-for-tree-table –

+0

你能提供一個表,你的結果尋找? –

+0

@TomasoAlbinoni,我在問題中添加了幾個結果表。請注意,每代都會產生不同的結果。我可以把它放在桌子上,但我每一代都在尋找桌子。 –

回答

1

這是冗長而醜陋的,並且會很慢,它只限於4代,但我不知道該怎麼辦。

SELECT person_name, parent_name FROM 

    (SELECT child1.name AS person_name, parent1.name AS parent_name, '1' AS generation 
    FROM people as child1 
    JOIN people as parent1 
    ON child1.parent_person_id = parent1.person_id AND child1.parent_person_id = child1.person_id 

    UNION 

    SELECT child2.name AS person_name, parent2.name AS parent_name, '2' AS generation 
    FROM people as child2 
    JOIN people as parent2 
    ON child2.parent_person_id = parent2.person_id AND child2.parent_person_id <> child2.person_id AND parent2.parent_person_id = parent2.person_id 

    UNION 

    SELECT child3.name AS person_name, parent3.name AS parent_name, '3' AS generation 
    FROM people as child3 
    JOIN people as parent3 
    ON child3.parent_person_id = parent3.person_id AND parent3.parent_person_id <> parent3.person_id 
    JOIN people as grandparent1 
    ON parent3.parent_person_id = grandparent1.person_id AND grandparent1.parent_person_id = grandparent1.person_id 

    UNION 

    SELECT child4.name AS person_name, parent4.name AS parent_name, '4' AS generation 
    FROM people as child4 
    JOIN people as parent4 
    ON child4.parent_person_id = parent4.person_id AND parent4.parent_person_id <> parent4.person_id 
    JOIN people as grandparent2 
    ON parent4.parent_person_id = grandparent2.person_id AND grandparent2.parent_person_id <> grandparent2.person_id 
    JOIN people as greatgrandparent 
    ON grandparent2.parent_person_id = greatgrandparent.person_id AND greatgrandparent.parent_person_id = greatgrandparent.person_id 
    ) AS tree 

WHERE generation = ? 
+0

這工作正常。我向子查詢添加了一個別名以避免錯誤1248.其他錯誤是第2代也返回第1代。 –

+0

感謝您的編輯。我修改了第2代以排除第1代。 –