Oracle SQL:如何查询所有子记录状态均为INACTIVE的父表数据
问题描述
父表(Parent Table)
| Parent ID | Parent Name |
|---|---|
| 1 | Parent A |
| 2 | Parent B |
子表(Child Table)
| Parent ID | Child ID | Status |
|---|---|---|
| 1 | Child A1 | ACTIVE |
| 1 | Child A2 | INACTIVE |
| 2 | Child B1 | INACTIVE |
| 2 | Child B2 | INACTIVE |
需求:编写Oracle SQL查询,仅返回所有子记录Status均为INACTIVE的父表详情。
预期输出
| Parent ID | Parent Name |
|---|---|
| 2 | Parent B |
本人是SQL新手,求解决思路和具体写法。
解决方法
方法1:GROUP BY + HAVING 筛选
这是最直观的分组筛选思路,先按父ID分组,验证分组内所有子记录的状态:
SELECT p."Parent ID", p."Parent Name" FROM "Parent Table" p JOIN "Child Table" c ON p."Parent ID" = c."Parent ID" GROUP BY p."Parent ID", p."Parent Name" HAVING COUNT(CASE WHEN c.Status = 'ACTIVE' THEN 1 END) = 0
解释:CASE WHEN会统计分组里状态为ACTIVE的子记录数量,等于0就说明该父ID下没有活跃子记录,符合要求。
方法2:NOT EXISTS 排除法
换个逻辑:找出不存在任何ACTIVE子记录的父记录,新手更容易理解:
SELECT p."Parent ID", p."Parent Name" FROM "Parent Table" p WHERE NOT EXISTS ( SELECT 1 FROM "Child Table" c WHERE c."Parent ID" = p."Parent ID" AND c.Status = 'ACTIVE' )
解释:子查询检查当前父ID是否有ACTIVE的子记录,NOT EXISTS表示没有这类子记录,也就是所有子记录都是INACTIVE。
方法3:使用ALL关键字
用ALL直接判断该父ID下所有子记录的状态都为INACTIVE:
SELECT p."Parent ID", p."Parent Name" FROM "Parent Table" p WHERE 'INACTIVE' = ALL ( SELECT c.Status FROM "Child Table" c WHERE c."Parent ID" = p."Parent ID" )
解释:子查询返回当前父ID的所有子状态,'INACTIVE' = ALL(...)要求所有返回的状态必须都是INACTIVE才满足条件。
新手提示
- 如果表名、字段名带空格,Oracle里必须用双引号
""包裹(实际建表建议尽量不用空格,避免麻烦)。 - 优先推荐方法2(NOT EXISTS),Oracle对这类关联子查询的优化效果较好,数据量大时效率更高。
内容的提问来源于stack exchange,提问作者Bhavish A S
相关产品推荐
相关产品推荐

