SQL查询:存在符合条件的父项目时排除对应子项目
问题解答
你初始写的SQL有两个明显问题:
- JOIN关联条件写错了,
p.parent_id = p.id是自指的错误逻辑,根本关联不到当前项目对应的父项目 - 用INNER JOIN做关联会漏掉parent_id为null的根节点,如果根节点本身符合选中条件,会被错误排除
筛选逻辑说明
按需求规则,最终要返回的记录只需要满足两个条件:
- 项目自身
is_chosen为true - 项目没有父项,或者直接父项的
is_chosen为false
不需要写递归CTE去判断所有层级的祖先:只要直接父项是选中状态,当前子项就该被排除;如果更高层级的祖先是选中状态,中间的父项会在它自己的匹配环节被上层过滤,最终自然会留下每一条选中链路最顶层的节点。
修正后可直接运行的SQL
SELECT p.id FROM "Projects" p LEFT JOIN "Projects" parent ON p.parent_id = parent.id WHERE p.is_chosen = true AND (parent.id IS NULL OR parent.is_chosen = false);
样例数据验证
代入你提供的测试数据,筛选所有is_chosen=true的记录逐一判断:
- id=2:父项为id=1,is_chosen=false → 保留
- id=3:父项为id=2,is_chosen=true → 排除
- id=7:父项为id=6,is_chosen=false → 保留
- id=8:父项为id=1,is_chosen=false → 保留
最终返回结果为2,7,8,和预期完全一致。
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

