我想有效地检查一个表是否包含任何匹配 的行.并且不匹配 ,其中条件是任意的.
在Oracle中,这几乎可以工作:
select count(*) from dual
where exists (
select * from people
where (<condition A>)
and not (<condition B>)
);
-- returns zero if all rows that match <condition A> also match <condition B>
-- (well, almost)
问题是可怕的空值.让我们说 是name =’Aaron’和 是年龄= 21.查询将正确识别年龄不等于21的任何Aarons,但无法识别年龄为null的任何Aarons.
这是一个正确的解决方案,但在包含数百万条记录的表上,可能需要一段时间:
select (
select count(*) from people
where (<condition A>)
) - (
select count(*) from people
where (<condition A>)
and (<condition B>)
) from dual;
-- returns zero if all rows that match <condition A> also match <condition B>
-- (correct, but it is s l o w...)
不幸的是,这两个条件将是任意的,复杂的,变化的,并且通常是我无法控制的.它们是从用户搜索的应用程序的持久性框架生成的,当我们尝试使用我们的用户保持索引时,很多时候它们会导致大表扫描(这就是为什么带有“exists”子句的第一个查询是比第二个快得多 – 它一旦找到一个匹配的记录就可以停止,而且不必进行两次单独的扫描.
如何在不充分利用空值的情况下有效地完成这项工作?
最佳答案 如果您有id字段,请尝试:
从双重中选择计数(*)
存在的地方(
选择*来自人
哪里(cond a)
和zzz.id没有(从人们中选择id(cond b))
);