我有层次结构表。如果用户查询id列表,则输出应该只是层次结构中任何提供的值的顶级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 :(得分: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将该列表定义为自己的表格并将第一个查询加入其中。