Uwaga: Ponieważ w odpowiedzi Sushant Butta ktoś twierdził, że link zewnętrzny jest martwy , opublikowałem tutaj treść jako oddzielną odpowiedź.
Uważaj na NULLS .
Dzisiaj natknąłem się na bardzo dziwne zachowanie zapytania podczas używania IN i NOT IN
operatorów. Właściwie chciałem porównać dwie tabele i dowiedzieć się, czy wartość z table b
istniała w, table a
czy nie, i dowiedzieć się, jak zachowuje się, jeśli kolumna zawiera null
wartości. Dlatego właśnie stworzyłem środowisko do testowania tego zachowania.
Stworzymy tabelę table_a
.
SQL> create table table_a ( a number);
Table created.
Stworzymy tabelę table_b
.
SQL> create table table_b ( b number);
Table created.
Wstaw niektóre wartości do table_a
.
SQL> insert into table_a values (1);
1 row created.
SQL> insert into table_a values (2);
1 row created.
SQL> insert into table_a values (3);
1 row created.
Wstaw niektóre wartości do table_b
.
SQL> insert into table_b values(4);
1 row created.
SQL> insert into table_b values(3);
1 row created.
Teraz wykonamy zapytanie, aby sprawdzić istnienie wartości table_a
, sprawdzając jej wartość table_b
za pomocą IN
operatora.
SQL> select * from table_a where a in (select * from table_b);
A
3
Wykonaj poniższe zapytanie, aby sprawdzić, czy nie istnieje.
SQL> select * from table_a where a not in (select * from table_b);
A
1
2
Wynik przyszedł zgodnie z oczekiwaniami. Teraz wstawimy null
wartość do tabeli table_b
i zobaczymy, jak zachowują się powyższe dwa zapytania.
SQL> insert into table_b values(null);
1 row created.
SQL> select * from table_a where a in (select * from table_b);
A
3
SQL> select * from table_a where a not in (select * from table_b);
no rows selected
Pierwsze zapytanie zachowało się zgodnie z oczekiwaniami, ale co się stało z drugim zapytaniem? Dlaczego nie otrzymaliśmy żadnych wyników, co powinno się stać? Czy jest jakaś różnica w zapytaniu? Nie .
Zmiana jest w danych tabeli table_b
. Wprowadziliśmy null
wartość do tabeli. Ale dlaczego tak się zachowuje? Podzielmy dwa zapytania na "AND"
i "OR"
operator.
Pierwsze zapytanie:
Pierwsze zapytanie będzie obsługiwane wewnętrznie, mniej więcej w ten sposób. Więc a null
nie spowoduje tutaj problemu, ponieważ moje pierwsze dwa operandy będą obliczane na true
lub false
. Ale mój trzeci operand a = null
nie będzie obliczany do true
ani false
. Oceni null
tylko.
select * from table_a whara a = 3 or a = 4 or a = null;
a = 3 is either true or false
a = 4 is either true or false
a = null is null
Drugie zapytanie:
Drugie zapytanie zostanie obsłużone jak poniżej. Ponieważ używamy "AND"
operatora i wszystko inne niż true
w którymkolwiek z operandów nie da mi żadnego wyniku.
select * from table_a whara a <> 3 and a <> 4 and a <> null;
a <> 3 is either true or false
a <> 4 is either true or false
a <> null is null
Jak więc sobie z tym radzimy? Wszystkie not null
wartości z tabeli wybierzemy table_b
używając NOT IN
operatora.
SQL> select * from table_a where a not in (select * from table_b where b is not null);
A
1
2
Dlatego zawsze uważaj na NULL
wartości w kolumnie podczas używania NOT IN
operatora.
Uważaj na NULL !!
in
Oświadczenie będzie analizowany identyczniefield=val1 or field=val2 or field=val3
. Umieszczenie tam wartości zerowej sprowadzi się do tego,field=null
co nie zadziała.