Как написать ниже запроса, не используя Not IN. Из-за соображений перфоманса IN, Не в не желательны.
select d.cert_serial_number as str from mdm_device d where d.client_id in (:CLIENT_IDS) and d.cert_serial_number not in (Select cert_serial_number from mdm_device where client_id not in (:CLIENT_IDS))
Интересующие столбцы таблицы:
| cert_serial_number | client_id |
+--------------------+------------+
| 102 | 1073741835 |
| 102 | 1073741836 |
| 102 | 1073741837 |
| 102 | 1073741838 |
| 102 | 1073741839 |
| 103 | 1073741840 |
| 103 | 1073741831 |
+--------------------+------------+------------+
Если входные данные cliend ids составляют 1073741835,1073741836, выход должен быть пустым.
Если входные данные cliend ids составляют 1073741835,1073741836,1073741837,1073741838,1073741839, выход должен быть равен 102.
EDIT: я закончил использовать следующий запрос: SELECT d.cert_serial_number AS str FROM mdm_device d где d.client_id в (: CLIENT_IDS) И НЕ СУЩЕСТВУЕТ (SELECT 1 FROM mdm_device e WHERE d.cert_serial_number = e.cert_serial_number И d.client_id! = e.client_id)
Ваша проблема связана с производительностью: ни один запрос не решит вашу проблему с производительностью, если вам не нужны ценные индексы или важный столбец, который бы захватил основные требования вашей системы.
Где те клиенты, которым вы не хотите, чтобы cert_serial_number был включен в ваши результаты? Возможно ли, что вы пропустили столбец, который бы чрезвычайно помог бы отличить эти сертификаты клиентов от ваших результатов?
Мое решение: я предлагаю вам вернуться к вашим требованиям и провести переоценку. Я уверен, что один из них создаст столбец где-нибудь и поможет вам получить результат с ожидаемой производительностью.
Предполагая, что ваш запрос верен, вы можете использовать его not exists
:
select d.cert_serial_number as str
from mdm_device d
where d.client_id in (:CLIENT_IDS) and
not exists (select 1
from mdm_device d2
where d2.cert_serial_number = d.cert_serial_number and
d2.client_id not in (:CLIENT_IDS)
);
Или вы можете использовать агрегацию:
select d.cert_serial_number as str
from mdm_device d
group by d.cert_serial_number
having sum(d2.client_id in (:CLIENT_IDS)) = count(*);
То есть, только возвратные устройства, которые имеют эти серийные номера, и другие.