如何实现'仅在'在oracle的条件?
我有两张桌子' PlanPlanSet'和' ExcludedPlans'。 PlanPlanSet包含与每个计划关联的计划和计划集。我想从PlanPlanSet中获取所有记录,其中只有在ExcludedPlans中进行Plan。
PlanPlanSet表
Deref
ExcludedPlans表
DerefMut
此处Planset1包含Plan1和Plan4,而Planset2仅包含Plan2。因此不应排除Planset1,应排除Planset2。
类似的东西,
Plan1 - Planset1
Plan2 - Planset2
Plan3 - Planset3
Plan4 - Planset1
Plan5 - Planset5
答案 0 :(得分:2)
这应该只能找到ExcludedPlans表中所有计划都存在的平面集。如果需要这些plansets的所有行,则省略第一行上的distinct并添加所需的任何列。
Select distinct planset
From PlanPlanSet ps1
Where
exists
(
Select selected.planset
From
(
Select ps2.planset, count(*) ct, sum(decode(ep2.plan, null, 0, 1)) present
From PlanPlanSet ps2
Left join ExcludedPlans ep2 on ep2.plan = ps2.plan
Group by ps2.planset
) selected
Where selected.ct = selected.present and ps1.planset = selected.planset
)
如果恰恰相反,只应选择ExcludedPlans表中不存在所有计划的此类计划集,则将子查询WHERE条件更改为selected.all<> selected.present
答案 1 :(得分:2)
您需要PLANSETS中的所有内容,其中该计划集中的每个计划都在排除计划列表中。
考虑到这种关系,您需要将两个表连接在一起,并发现每一方的计划数量相同。这意味着我们必须允许它们不同,这意味着LEFT OUTER JOIN。
select p.planset
from plansets p
left outer join excludedplans e
on p.plan = e.plan
group by p.planset
having count(p.plan) = count(e.plan)
这假设PLANSETS在PLANSET和PLAN上是唯一的,并且EXCLUDEDPLANS在PLAN上是唯一的。如果此假设不正确,则您需要count(distinct ...
如果您想获得PLANSETS的所有数据,那么可以将逻辑放入分析函数
select *
from ( select p.*
, count(p.plan) over (partition by p.planset) as planset_ct
, count(e.plan) over (partition by p.planset) as excluded_ct
from plansets p
left outer join excludedplans e
on p.plan = e.plan
)
where planset_ct = excluded_ct
答案 2 :(得分:0)
此查询返回PlanPlanSet
中仅包含排除计划集的所有记录:
select * from PlanPlanSet pss
where not exists
( select planname from planPlanSet x
where x.setname = pss.setname
minus
select planname from ExcludedPlans)
/
MINUS运算符从顶部子查询生成一组记录,这些记录在底部子查询中不存在。当结果为空集时,计划集仅包含排除的计划。 MINUS不是一个非常快速的操作,因此如果您要处理大量记录,这可能不是最好的方法。但是,它确实具有检索PlanPlanSet
列的优势,而不仅仅是setname
。