postgreSQL SELECT排除子节点,如果父节点存在



我们有一个Projects表,其中项目可以由projectA.parent_id = projectB.id嵌套。

在选择满足给定条件的所有项目时,如何只选择如果两个元素都满足它(或者父元素满足它),则使用,并且只使用如果孩子遇到了它?

<表类> id parent_id is_chosen tbody><<tr>1空假21真正32对41假54假61假76对81对98假

可以合并两个查询,一个用于父查询,一个用于子查询。例如:

select distinct *
from (
select p.* -- finding parents
from projects p
join projects c on c.parent_id = p.id
where p.is_chosen
union all
select c.* -- finding children
from projects p
join projects c on c.parent_id = p.id
where not p.is_chosen and c.is_chosen
) x

结果:

id  parent_id  is_chosen 
--- ---------- --------- 
2   1          t         
8   1          t         
7   6          t         

参见示例:db<>fiddle。

应该可以简化为:

SELECT p.id
FROM parents p
WHERE is_chosen = 'true'
AND NOT EXISTS (SELECT *
FROM parents p2
WHERE p2.is_chosen = 'true'
AND p2.id = p.parent_id)

可以这样使用CTE

WITH CTE AS (
SELECT *
FROM tab 
WHERE is_chosen
)
SELECT
id
FROM CTE t
WHERE NOT EXISTS (
SELECT 
FROM CTE
WHERE id = t.parent_id
)

演示

相关内容