[英]SQL Query which depends on the existence of other rows
I have the following table structure (and data example): 我具有以下表结构(和数据示例):
id code category 1 x c1 1 y c1 1 a c2 2 y c1 2 a c2 3 a c2 4 j c3
Given a list of pairs <(category, code)>, one for each category, I need to query the ids
which match the pairs. 给定一个对<(类别,代码)>的列表,每个类别一个,我需要查询与这些对匹配的
ids
。 The rule is: if a category is present for the id
, its pair must be in the list for the id
to be returned. 规则是:如果
id
存在一个类别,则其对必须在列表中才能返回id
。
For example, if the input pairs are (c1, x), (c2, a), (c3, k) the ids
to be returned are: 1 and 3. 例如,如果输入对为(c1,x),(c2,a),(c3,k),则返回的
ids
为:1和3。
2 must not be returned, because the c1
category does not match the code x
. 不得返回2,因为
c1
类别与代码x
不匹配。
3 is returned because for the only category present, the code matches a
. 之所以返回3,是因为对于唯一的类别,代码与
a
相匹配。
I've tried using (EXISTS(c1 and code) or NOT EXISTS(c1)) AND (EXISTS(c2 and code) or NOT EXISTS(c2)) AND...
but could not eliminate id=2
from the results. 我试过使用
(EXISTS(c1 and code) or NOT EXISTS(c1)) AND (EXISTS(c2 and code) or NOT EXISTS(c2)) AND...
但是无法从结果中消除id=2
。
Made it work with the following query: 通过以下查询使其工作:
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>
I would do it like here: 我会在这里这样做:
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;
This way you don't have to write all these new not exist... or exists...
clauses, and data is hit only once (important from performance point of view). 这样,您不必编写所有这些新的
not exist... or exists...
子句,并且数据仅被命中一次(从性能角度来看很重要)。
If you can stuff your (category, code) pairs into something table-like, you could just join and group by id. 如果您可以将您的(类别,代码)对塞入类似表格的表中,则可以按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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.