2015-12-08 128 views
0

我有層次結構表。如果用戶查詢ID列表,則輸出應該只是任何提供的值的層次結構中的頂級ID。如果列表中有父母標識,則應該返回,否則應該返回孩子標識。從父子層次結構表中獲取頂級父ID身份證

下面是桌子和一個例子:

id parentid 
------------- 
1 | null 
2 | 1 
3 | 1 
4 | 2 
5 | 4 
6 | 3 

如果我查詢2,4,5,6我需要輸出2,6

輸出不應返回4(如父母2已經在列表中),並且不應該返回5,因爲頂級父級(5 - > 4 - > 2)在提供的列表中也可用。

即,如果提供的列表包含來自同一層次的值,則只應該在輸出中爲該特定層次返回TOP層次結構節點。

回答

0

我不是你的意思與爲什麼5將不包括在輸出完全清楚,但是這會給你的結果:

select id from mytable where id in (2,4,5,6) and parentid not in (2,4,5,6) 

去不止一個級別中排除值,你將不得不將自己加入桌子。事情是這樣的:

select id from mytable join mytable parenttab on mytable.parentid = parenttab.id 
where mytable.id in (2,4,5,6) and 
     mytable.parentid not in (2,4,5,6) and 
     parenttab.parentid not in (2,4,5,6) 

如果你想去層次結構的任何級別,您將需要使用recursive CTE。類似這樣的:

WITH RecursiveParentList (parentid) 
AS 
(
    SELECT parentid from Mytable 
    where id in (2,4,5,6) 

    UNION ALL 

    SELECT ParentTable.id 
     FROM Mytable AS ParentTable 
     INNER JOIN RecursiveParentList AS ChildTable 
       ON ParentTable.id = ChildTable.parentid 
) 
SELECT MyTable.id 
    FROM MyTable 
     LEFT JOIN RecursiveParentList on MyTable.id = RecursiveParentList.id 
WHERE RecursiveParentList.id is null; 

注意1:您將需要調試此。我把它從頭頂拉下來,不會測試它。注2:我只使用IN子句來做這樣的簡短小清單。如果您排除的項目列表變長或從另一個表格中拉出,您將希望使用另一個CTE將該列表定義爲其自己的表格,並將第一個查詢連接到該列表。

+0

5是2(2 - > 4 - > 5)的層級子,因爲2在輸出5中不應該存在 – Annavi

+0

那麼,我給你的SQL會給你你想要的結果,但是僅僅因爲5在層次4 - > 5中,並且由於4在列表中,所以其父項被省略。所以這隻會在層級中上升一級。如果你想更深入,你將不得不加入到自己的桌子。你想要走多深?足夠兩個級別? – AgapwIesu

+0

它應該是任何級別的層次結構 – Annavi