如何在oracle中实现'Only in'条件?

问题描述 投票:1回答:3

如何在oracle中实现'Only in'条件?

我有两个表'PlanPlanSet'和'ExcludedPlans'。 PlanPlanSet包含与每个计划关联的计划和计划集。我想从PlanPlanSet中获取所有记录,其中只有ExcludedPlans中的Plan。

PlanPlanSet表

Plan1 - Planset1
Plan2 - Planset2
Plan3 - Planset3
Plan4 - Planset1
Plan5 - Planset5

ExcludedPlans表

Plan1
Plan2

此处Planset1包含Plan1和Plan4,而Planset2仅包含Plan2。因此不应排除Planset1,应排除Planset2。

就像是,

select pps.planset 
from PlanPlanSet pps 
 where pps.planNumber only in (select ex.planNumber 
                               from ExcludedPlan ex);
sql oracle having
3个回答
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
投票

这应该只能找到这样的计划集,其中所有计划都存在于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


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

LiveSQL demo.

© www.soinside.com 2019 - 2024. All rights reserved.