Я хочу эффективно проверить, содержит ли таблица любые строки, которые соответствуют < условиям A > и не соответствуют < условиях B >, где условия произвольные.Отрицание произвольного условия условия where (включая нулевые тесты)
В 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)
Проблема заключается в помышляли нулевые значения. Допустим, < состояние A > is name = 'Aaron' и < состояние B > is возраст = 21. Запрос будет правильно идентифицировать любые аароны, возраст которых не равен 21, но он не может идентифицировать Ааронов, возраст которых равен нулю.
Вот это правильное решение, но на столе с миллионами записей может занять некоторое время:
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...)
К сожалению, эти два условия будут произвольными, комплекс, меняется, и вообще вне моего контроля. Они генерируются из структуры персистентности приложений из пользовательских запросов, и, хотя мы стараемся поддерживать наши индексы с нашими пользователями, много времени они будут вызывать большое сканирование таблицы (поэтому первый запрос с предложением «существует» намного быстрее, чем второй - он может остановиться, как только он найдет одну подходящую запись, и ей не нужно делать два отдельных сканирования).
Как я могу сделать это эффективно, не запускаясь по нулям?
где nvl2 (age_column, age_parameter, null)? – glasnt