Query не использует «Not IN» в SQL

0

Как написать ниже запроса, не используя 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)

  • 0
    Что вы написали, похоже, это должно работать? Что говорит ваш SQL
Теги:
notin

2 ответа

0

Ваша проблема связана с производительностью: ни один запрос не решит вашу проблему с производительностью, если вам не нужны ценные индексы или важный столбец, который бы захватил основные требования вашей системы.

Где те клиенты, которым вы не хотите, чтобы cert_serial_number был включен в ваши результаты? Возможно ли, что вы пропустили столбец, который бы чрезвычайно помог бы отличить эти сертификаты клиентов от ваших результатов?

Мое решение: я предлагаю вам вернуться к вашим требованиям и провести переоценку. Я уверен, что один из них создаст столбец где-нибудь и поможет вам получить результат с ожидаемой производительностью.

0

Предполагая, что ваш запрос верен, вы можете использовать его 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(*);

То есть, только возвратные устройства, которые имеют эти серийные номера, и другие.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню