SQL查询依赖于其他行的存在

时间:2015-07-15 22:51:32

标签: sql oracle

我有以下表结构(和数据示例):

id  code category
1   x    c1    
1   y    c1    
1   a    c2
2   y    c1
2   a    c2
3   a    c2
4   j    c3

给定一对<(类别,代码)>的列表,每个类别一个,我需要查询匹配对的ids。规则是:如果id存在类别,则其对必须位于要返回id的列表中。

例如,如果输入对是(c1,x),(c2,a),(c3,k),则返回的ids为:1和3.

不得返回

2,因为c1类别与代码x不匹配 返回3是因为对于唯一存在的类别,代码与a匹配。

我已尝试使用(EXISTS(c1 and code) or NOT EXISTS(c1)) AND (EXISTS(c2 and code) or NOT EXISTS(c2)) AND...但无法从结果中删除id=2

3 个答案:

答案 0 :(得分:1)

使用以下查询:

select distinct t2.ID from t t2
where
( not exists (select * from t where id = t2.id and cat like 'c2') 
or (exists ( select * from t where id = t2.id and cat = 'c2' and code = 'a')))
and
(not exists (select * from t where id = t2.id and cat like 'c1') 
or (exists( select * from t where id = t2.id and cat = 'c1' and code = 'x')))
and
(not exists (select * from t where id = t2.id and cat like 'c3') 
or (exists( select * from t where id = t2.id and cat = 'c3' and code = 'k')))
; </pre>

答案 1 :(得分:1)

我会这样做:

with input(cat, code) as (select 'c1', 'x' from dual 
                union all select 'c2', 'a' from dual
                union all select 'c3', 'k' from dual)
select id from (
  select t.id, max(decode(i.code, t.code, 1, 0)) cc from t
    left join input i on i.cat = t.cat and i.code = t.code
    group by t.id, t.cat)
  group by id having min(cc) = 1;

SQLFiddle demo

这样您就不必编写所有这些新的not exist... or exists...子句,并且数据只被命中一次(从性能的角度来看很重要)。

答案 2 :(得分:0)

如果您可以将您的(类别,代码)对填充到类似于表的内容中,则可以按ID加入和分组。

SELECT id
FROM table
JOIN ( 
    SELECT category1, code1
    UNION SELECT category2, code2
    ...
) 
ON table.category = pairs.category AND table.code = pairs.code
GROUP BY id