2015-12-08 133 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