2017-01-06 36 views
5

Ostatnio zdarzyło mi się natrafić na nie() w Sql Server i Oracle. Próbowałem różnych przykładów porównujących warunki NOT i nie() z różnymi operatorami, takimi jak LIKE, IN itp. Nie widzę żadnej różnicy pod względem zestawu wyników i liczby rekordów, ale chcę potwierdzić za pomocą wspólnoty, jeśli oba z nich robią to samo lub jakiekolwiek zastrzeżenie?Jaka jest różnica między warunkiem NOT a NOT() w Oracle i MS SQL Server

Przykład Zapytania

select count(*) from Emp where country not in ('ENGLAND UK', 'HAITI', 'IRELAND') 
select count(*) from Emp where not(country in ('ENGLAND UK', 'HAITI', 'IRELAND')) 
+0

W programie SQL Server można uzyskać serwer do generowania planów wykonania. Następnie można porównać plany wykonania dla tych dwóch zapytań i zobaczyć, że są one identyczne. W Oracle istnieje podobna funkcjonalność pod inną nazwą. –

+0

SQL 2014 i 2016: z literalną listą argumentów w klauzuli 'IN()', brak różnic w planach wykonania SQL. jeśli zaangażowana jest kolumna PK, będzie to wyszukiwanie w indeksie klastrowym, w przeciwnym razie sklasyfikowane w indeksie. z podkwerendą i optymalnymi kluczami, będą to dwa skany i lewe anti semi join, bez względu na to, gdzie znajduje się operator "NOT". – dlatikay

Odpowiedz

2

Oba miejsca docelowe słowa kluczowego NOT są logicznie równoważne i dają takie same wyniki. NOT przed wyrażeniem w nawiasach odwraca wynik tego wyrażenia, ale jest to konwencjonalna logika boolowska i nie jest specyficzna dla SQL.

W T-SQL plany wykonania są takie same w SQL Server 2014 i SQL Server 2016 w przypadku przykładów (założenie: tabela ma klucz podstawowy, a country nie jest indeksowana).

Jest jedno zastrzeżenie szczególnie z podanymi przykładami: Operator IN zachowuje się inaczej niż można by się spodziewać, gdy jego argumenty mają wartości NULL. W przypadku Oracle, see here;

dla T-SQL, należy rozważyć to:

select 1 where 'A' in (null) 

To nie zwróci wiersz.Co wydaje się banalne, ale:

select 1 where 'A' not in (null) 

To oświadczenie nie zwróci eiher wiersza. Teraz możemy argumentować, jeśli logicznie odwrócić wyraz z pierwszego zestawienia jak ta, to zdecydowanie powinien zwrócić wiersz:

select 1 where not ('A' in (null)) 

Ale tak nie jest, ponieważ IN (NULL) ocenia się neither true nor false.

1

w Twoim przypadku, nie prawdziwa różnica

Spójrz na to jednak:

where x1 not in ('a','b','c') 
and x2 not in ('x','y','z') 

To może być zapisana jako

where not (x1 in ('a','b','c') 
      or x2 in ('x','y','z')) 

Pisząc zapytania , czasami używam or, kiedy identyfikuję to, co chcę wykluczyć. Łatwiej jest po prostu użyć not() niż przepisać or do and ... not ...

3

Różnica będzie tam, gdy masz inny warunek z AND/OR. To odwraca AND do OR i OR do AND

select 1 where not(1 = 1 or 1 <> 1) 

będzie taka sama jak

select 1 where (1 <> 1 and 1 = 1) 

i

select 1 where not(1 = 1 and 1 <> 1) 

będzie taka sama jak

select 1 where (1 <> 1 or 1 = 1) 

i

select 1 where not(1 = 1) or 1 = 1 

nie będzie taki sam jak

select 1 where not(1 = 1 or 1 = 1)