在Oracle中选择多个值的交集

时间:2018-12-12 12:38:57

标签: sql oracle

我有一个SQL问题,需要您的帮助。我正在从工作流(特定于应用程序的术语)查询Oracle数据库。我需要从一个看起来像下面的表中获得正确的分类值,并给出CRI_ID列表。

    CAT             CRI_ID
    268_0_43_BR     506
    268_0_43_BR     507
    268_0_43_BR     508
    268_0_43_BR     509
    462_406_42_TR   508
    462_406_42_TR   509

看似简单,但问题是同一CRI_ID可以具有多个CAT。因此,基本上我将拥有一个包含$ CRI_ID列表的变量$ {CRI_IDs}。以此为例:

  • $ {CRI_IDs} = 506,507, 508,509 >>预期的CAT = 268_0_43_BR
  • $ {CRI_IDs} = 508,509 >>预期的CAT = 462_406_42_TR

这将无法使用连接/相交/子查询,因为我总是会同时获得两个类别。知道在这种情况下什么是合适的查询吗?

我已经尝试过以下方法,但它会同时返回两个类别。

    select cat from table where cri_id in (${CRI_IDs});
    select table.cat from table join (select ${CRI_IDs} from dual) tmp on table.cri_id=tmp.id;

顺便说一句,顺便说一句,BTW可以代替变量,而我拥有另一个表(例如tmp),该表的其中一列包含CR_ID列表

1 个答案:

答案 0 :(得分:1)

使用GROUP BYHAVING

select cat
from t
group by cat
having sum(case when cri_id in (506, 507, 508, 509) then 1 else 0 end) = 4 and
       sum(case when cri_id not in (506, 507, 508, 509) then 1 else 0 end) = 0;

having子句计算行如何满足每种条件。第一种是寻找id所需的cat= 4指定所有都必须存在,假设该表没有重复项。 (重复项易于处理,但会使查询稍微复杂化。)

第二个条件在列表中寻找cri_id not = 0指定找不到任何内容。