Запрос в Oracle не соответствует условиям AND и WHERE - PullRequest
0 голосов
/ 01 марта 2019

У меня есть этот запрос в Oracle:

SELECT serverHostName,
      operatingSystem,
      serverClass
FROM Server_Inventory A
WHERE A.serverHostName NOT IN 
    (SELECT rltd_ServerHostname
     FROM App_Server_Relationship)
AND A.serverHostName NOT IN 
    (SELECT rltd_ServerHostname
     FROM DataBase_Server_Relationship)
AND A.operatingSystem NOT IN ('OS1','OS3','OS5')
AND A.serverClass NOT IN ('CLASS_3','CLASS_6');

Я пытаюсь получить список серверов из моей таблицы Server_Inventory, на которых нет приложения и базы данных, связанных или связанных с ним.,Я получаю некоторые результаты, но после некоторой ручной проверки я заметил, что некоторые серверы были исключены, даже если они не подпадают под условия исключения.Например, допустим, у меня есть сервер с именем «Server_24GW1».Если я выполню запрос следующим образом:

SELECT serverHostName,
      operatingSystem,
      serverClass
FROM Server_Inventory A
WHERE A.serverHostName NOT IN 
    (SELECT rltd_ServerHostname
     FROM App_Server_Relationship)
AND A.serverHostName NOT IN 
    (SELECT rltd_ServerHostname
     FROM DataBase_Server_Relationship)

При поиске сервера Server_24GW1 я получу следующий результат:

serverHostName   |  operatingSystem   | serverClass
----------------------------------------------------
Server_24GW1     |   (null)           |  CLASS_10

Но если я выполню запрос с условиями, то естьэто:

AND A.operatingSystem NOT IN ('OS1','OS3','OS5')
AND A.serverClass NOT IN ('CLASS_3','CLASS_6');

Ничего не получается, когда я пытаюсь найти Server_24GW1, даже если operatingSystem и serverClass не попадают под исключающие условия.

Кто-нибудь знает, чтомогу ли я быть не прав?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

A.operatingSystem NOT IN ('OS1','OS3','OS5') является синтаксическим сочетанием клавиш, эквивалентным:

NOT (A.operatingSystem = 'OS1' OR A.operatingSystem ='OS3' OR A.operatingSystem ='OS5')

Если A.operatingSystem IS NULL, то вы пытаетесь сравнить NULL, используя равные , и что всегда терпит неудачу.

Чтобы преодолеть это, необходимо учитывать возможность NULL для сравнений, например,

AND (A.operatingSystem NOT IN ('OS1','OS3','OS5') OR A.operatingSystem IS NULL) 

NB: можно использовать NVL () или COALESCE () в качествеальтернативно, но, если использовать такой подход, условие не сможет использовать индекс, и это может отрицательно повлиять на производительность запроса (, если не существует соответствующего индекса на основе функции ).

0 голосов
/ 01 марта 2019

NULL работают иначе, чем все остальные

Попробуйте это.Хотя это, вероятно, прекратит использование индекса на operatingSystem, логика сработает так, как вы хотите.

AND NVL(A.operatingSystem,' ') NOT IN ('OS1','OS3','OS5')

Или это

AND (A.operatingSystem NOT IN ('OS1','OS3','OS5') OR A.operatingSystem IS NULL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...